React TypeScript 如何实现interface中两个属性二选一必填
实现TypeScript接口属性二选一必填的方案
你可以通过TypeScript的联合类型+never类型限定,实现两个属性二选一必填的校验,具体实现如下:
方案1:拆分接口为联合类型(最直观易维护)
先抽离公共属性,再拆分不同属性组合的分支接口,最终合并为联合类型即可:
// 抽离所有公共属性 interface TableContentBaseProps { Data?: any; HideType: "above" | "below" | "none"; } // 分支1:必须传HideBelow,不能传HideAbove interface TableContentWithHideBelow extends TableContentBaseProps { HideBelow: "sm" | "md" | "lg" | "xl"; HideAbove?: never; } // 分支2:必须传HideAbove,不能传HideBelow interface TableContentWithHideAbove extends TableContentBaseProps { HideAbove: "sm" | "md" | "lg" | "xs"; HideBelow?: never; } // 最终的Props类型 type TableContentProps = TableContentWithHideBelow | TableContentWithHideAbove
如果需要兼容HideType: "none"时两个属性都不传的场景,再加一个分支即可:
interface TableContentWithNoneHide extends TableContentBaseProps { HideType: "none"; HideBelow?: never; HideAbove?: never; } // 合并三个分支 type TableContentProps = TableContentWithHideBelow | TableContentWithHideAbove | TableContentWithNoneHide
额外优化:和HideType联动校验
如果需要保证属性和HideType取值匹配(比如HideType为above时只能传HideAbove),可以在分支接口中限定HideType的取值:
interface TableContentWithHideBelow extends TableContentBaseProps { HideType: "below"; // 限定HideType只能是below HideBelow: "sm" | "md" | "lg" | "xl"; HideAbove?: never; } interface TableContentWithHideAbove extends TableContentBaseProps { HideType: "above"; // 限定HideType只能是above HideAbove: "sm" | "md" | "lg" | "xs"; HideBelow?: never; }
方案2:通用互斥工具类型(适合重复场景)
如果项目中经常需要用到多属性互斥二选一的逻辑,可以封装通用工具类复用:
// 通用二选一工具类型:传入属性集合,要求只能传其中一个 type OnlyOne<T, K extends keyof T = keyof T> = K extends keyof T ? Omit<T, K> & Required<Pick<T, K>> & Partial<Record<Exclude<keyof T, K>, never>> : never; // 基础属性定义 interface TableContentBaseProps { Data?: any; HideType: "above" | "below" | "none"; HideBelow?: "sm" | "md" | "lg" | "xl"; HideAbove?: "sm" | "md" | "lg" | "xs"; } // 最终Props:公共属性 + HideBelow和HideAbove二选一校验 type TableContentProps = Omit<TableContentBaseProps, 'HideBelow' | 'HideAbove'> & OnlyOne<Pick<TableContentBaseProps, 'HideBelow' | 'HideAbove'>>
校验效果
以上两种方案都可以实现以下校验规则:
- 仅传HideBelow:校验通过
- 仅传HideAbove:校验通过
- 同时传两个属性:TS直接抛出错误,提示对应属性不允许存在
- 两个属性都不传:TS抛出错误,提示需要传递其中一个属性
内容的提问来源于stack exchange,提问作者IceJonas
相关产品推荐
相关产品推荐

