React项目中使用TypeScript接口实现组件互斥属性校验
解决方案
你需要将原有的普通联合类型改造为互斥联合类型,同时在组件内部做类型收窄,具体实现如下:
1. 类型改造
首先定义工具类型实现两个接口的属性互斥,确保使用其中一个接口的属性时,无法传入另一个接口的独有属性:
interface IFirst { name: string, age: number } interface ISecond { name: string, cars: number, friends: number } // 互斥联合工具类型:A和B的独有属性不能同时存在 type MutexUnion<A, B> = | (A & Partial<Record<Exclude<keyof B, keyof A>, never>>) | (B & Partial<Record<Exclude<keyof A, keyof B>, never>>) type ICommon = MutexUnion<IFirst, ISecond>;
2. 组件改造
组件内部不能直接解构所有属性,需要先通过类型判断收窄类型,避免TS报错属性不存在:
const Element: React.FC<ICommon> = (props) => { // 类型收窄:判断当前props为IFirst类型 if ('age' in props) { return <div>Hello {props.name} {props.age}</div> } // 剩余分支自动识别为ISecond类型 return <div>Hello {props.name} {props.cars}, {props.friends}</div> } const Parent = () => { // 此处传入cars/friends会触发TS报错 return <Element name={'J'} age={11}/> } export default function App() { return ( <div className="App"> {/* 此处传入age会触发TS报错 */} <Element name={'B'} cars={2} friends={6}/> <Parent/> </div> ); }
实现原理
- 互斥联合类型会将另一个接口的独有属性标记为
never类型,只要传入不符合当前类型的属性,TS就会直接抛出类型错误,满足你两种传参模式互斥的需求。 - 组件内部通过
in操作符判断属性是否存在,TS会自动收窄当前分支的props类型,不会再出现属性不存在的报错。
内容的提问来源于stack exchange,提问作者Asking
相关产品推荐
相关产品推荐

