You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React TypeScript组件Props校验:如何限制onClick与component不同时传入

解决方案

你的问题出在原类型定义把「可选属性」强制变成了「必传属性」,同时用never的方式过于严苛,不符合你“二者均为可选、仅在需要时传入”的需求。

正确的类型定义写法

直接通过联合类型结合可选属性+互斥约束实现:

import React from 'react';

interface Common {
  /** 公共属性 **/
  className?: string;
  // 其他公共属性...
}

// 允许传入 onClick(可选),但不能传 component
type WithOnClick = Common & {
  onClick?: () => void;
  component?: never;
};

// 允许传入 component(可选),但不能传 onClick
type WithComponent = Common & {
  component?: React.ReactElement<HTMLElement>;
  onClick?: never;
};

// 最终的组件Props类型
type MainProps = WithOnClick | WithComponent;

写法说明

  1. 把onClick和component都设为可选属性,满足“仅在需要时传入”的要求;
  2. 通过component?: never和onClick?: never约束:当传入其中一个属性时,另一个属性无法被传入(TypeScript会直接抛出类型错误);
  3. 联合类型WithOnClick | WithComponent自动包含了「都不传入」的情况,无需额外添加Common类型。

验证效果

  • 只传onClick:类型校验通过;
  • 只传component:类型校验通过;
  • 都不传:类型校验通过;
  • 同时传onClick和component:TypeScript直接抛出错误,符合互斥要求。

通用互斥类型工具(可选)

如果需要复用这种“二选一”的约束逻辑,可以实现一个通用的XOR类型:

// 通用互斥类型工具
type XOR<T, U> = (T | U) extends object 
  ? (Omit<T, keyof U> & U) | (Omit<U, keyof T> & T) 
  : T | U;

interface Common {
  /** 公共属性 **/
}

type MainProps = Common & XOR<
  { onClick?: () => void }, 
  { component?: React.ReactElement<HTMLElement> }
>;

这个工具可以用来约束任意两组互斥的可选属性,扩展性更强。

内容的提问来源于stack exchange,提问作者Jake

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 19:20:30