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

如何根据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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 07:41:24