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

基于判别联合/泛型的Props无法被TypeScript推断

解决TypeScript条件Props推断失败的问题

问题本质

你的报错是因为TypeScript没法正确识别联合类型的分支,核心原因:

  1. 给multipleSelection加默认值后,类型被自动拓宽成boolean,破坏了判别联合的类型区分逻辑
  2. 泛型方案里没让TypeScript自动推导MS类型,同时默认值的类型约束没处理好

方案1:修复判别联合类型的类型收窄

把默认值移到函数内部处理,不要在参数解构时设置,保留联合类型的判别能力:

type DataFilteringBaseProps = {
  buttonClassname?: string;
  // 其他基础属性
};

type MultipleSelectionProps<T> = {
  multipleSelection: true;
  criteriaList: T[];
  filtering: boolean; // 多选特有的属性
};

type SingleSelectionProps = {
  multipleSelection: false;
  // 单选特有的属性
};

type DataFilteringButtonProps<T extends string> = DataFilteringBaseProps & (
  | SingleSelectionProps
  | MultipleSelectionProps<T>
);

function DataFilteringButton<T extends string>(
  props: DataFilteringButtonProps<T>
) {
  // 内部处理默认值,不破坏联合类型
  const { multipleSelection = false, buttonClassname, ...rest } = props;

  // 此时TypeScript能正确收窄类型
  if (multipleSelection) {
    // rest自动推断为MultipleSelectionProps<T>类型,可直接访问filtering、criteriaList
    console.log(rest.criteriaList, rest.filtering);
  } else {
    // rest自动推断为SingleSelectionProps类型
    console.log("单选模式");
  }

  return <button className={buttonClassname}>筛选</button>;
}

注意:不要在函数参数的解构中给multipleSelection设默认值,否则TypeScript会把它的类型从true | false拓宽成boolean,导致联合类型的判别失效。


方案2:优化泛型方案,实现自动类型推导

如果偏好泛型写法,要让TypeScript根据传入的props自动推导泛型参数,同时设置合理的默认值:

type DataFilteringBaseProps = {
  buttonClassname?: string;
};

type MultipleSelectionProps<T> = {
  multipleSelection: true;
  criteriaList: T[];
  filtering: boolean;
};

type SingleSelectionProps = {
  multipleSelection: false;
};

// 给MS设置默认泛型参数为false,对应单选模式
type DataFilteringButtonProps<
  T extends string,
  MS extends boolean = false
> = DataFilteringBaseProps & (MS extends true ? MultipleSelectionProps<T> : SingleSelectionProps);

function DataFilteringButton<T extends string, MS extends boolean = false>(
  props: DataFilteringButtonProps<T, MS>
) {
  const { multipleSelection = false as MS, buttonClassname } = props;

  if (multipleSelection) {
    // 此时props会自动推断为多选类型,可直接访问对应属性
    console.log(props.criteriaList, props.filtering);
  } else {
    console.log("单选模式");
  }

  return <button className={buttonClassname}>筛选</button>;
}

// 使用示例
DataFilteringButton({ multipleSelection: true, criteriaList: ["a", "b"], filtering: true });
DataFilteringButton({ multipleSelection: false });
DataFilteringButton({}); // 自动使用默认的单选模式

注意:给泛型MS设置默认值false,这样不传multipleSelection时会自动匹配单选类型;解构时用as MS约束默认值类型,避免类型拓宽。


避坑总结

  • 判别联合类型的核心是保持判别属性的类型为true | false,不要通过默认值把它变成boolean
  • 泛型方案尽量让TypeScript自动推导参数,不要手动指定,保证类型和传入的props匹配

内容的提问来源于stack exchange,提问作者user28586336

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 21:03:31