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;
写法说明
- 把
onClick和component都设为可选属性,满足“仅在需要时传入”的要求; - 通过
component?: never和onClick?: never约束:当传入其中一个属性时,另一个属性无法被传入(TypeScript会直接抛出类型错误); - 联合类型
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
相关产品推荐
相关产品推荐

