如何根据multi Prop定义items为number或number[]类型?
问题描述
我希望实现:当组件的multi属性为true时,items属性的类型为number[];当multi为false或未传入时,items类型为number。
我尝试了如下写法但不符合TypeScript语法:
interface EnhancedSelectProps { items: multi ? number[] : number; multi?: boolean; } const EnhancedSelect = ({ items, multi, }: EnhancedSelectProps) => {}
之后我使用了联合类型,但在判断multi为true时访问items.length会触发TypeScript错误:
interface EnhancedSelectProps { items?: number[] | number; multi?: boolean; } const EnhancedSelect = ({ items, multi, }: EnhancedSelectProps) => { if(multi) console.log(items.length); else console.log(items) }
请问如何正确实现这种根据其他Prop动态约束类型的需求?
解决方案
要实现这种根据其他属性动态约束类型的需求,得用TypeScript的区分联合类型(Discriminated Union)——这是TS处理这类关联属性类型约束的标准方案,能让TS自动完成类型收窄,不会再出现无意义的类型报错。
1. 定义区分联合类型的Props
别用单一接口,把EnhancedSelectProps拆成两个场景的联合类型:
type EnhancedSelectProps = | { multi: true; items: number[] } | { multi?: false; items: number };
核心逻辑很明确:
- 只要
multi设为true,items就必须是number[] - 要是
multi是false或者完全不传,items只能是number - 靠
multi这个“区分符”,TS能精准判断items的类型
2. 在组件中使用类型收窄
现在在组件里判断multi的时候,TS会自动把items的类型收窄到对应分支,访问length之类的属性再也不会报错:
const EnhancedSelect = ({ items, multi, }: EnhancedSelectProps) => { if (multi) { // TS明确知道这里items是数组,放心调用length console.log(items.length); } else { // 这里TS确定items是单个number console.log(items); } };
可选优化:更严格的类型约束
要是想彻底避免“不传multi但传数组”的错误写法,可以把第二个分支的multi设为never:
type EnhancedSelectProps = | { multi: true; items: number[] } | { multi?: never; items: number };
这样当你没传multi的时候,items就只能是number,从类型层面直接杜绝了误用。
内容的提问来源于stack exchange,提问作者Sky
相关产品推荐
相关产品推荐

