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

基于属性值的条件类型:TypeScript组件Props类型定义难题

解决TypeScript中组件Props的条件类型依赖问题

你遇到的问题很典型——在TypeScript里直接在对象类型中用属性值做条件判断是行不通的,因为类型定义层面无法直接引用属性名作为判断依据。不过我们可以用判别式联合类型(Discriminated Union)来完美解决这个需求,让onToggle的类型严格依赖collapsible的取值。

具体实现方式

我们可以把组件的Props拆分成两种明确的类型,再合并成联合类型:

// 当collapsible为true时,onToggle必须是一个无参函数
type CollapsibleStateProps = {
  collapsible: true;
  onToggle: () => void;
};

// 当collapsible为false时,onToggle必须是undefined
type NonCollapsibleStateProps = {
  collapsible: false;
  onToggle: undefined;
};

// 合并成最终的Props类型
type Props = CollapsibleStateProps | NonCollapsibleStateProps;

为什么这样可行?

这里的collapsible就是一个判别式——TypeScript会根据它的布尔值,自动推断出当前Props对应的子类型。在组件内部使用时,TypeScript还会帮你做类型收窄:

const MyComponent = (props: Props) => {
  if (props.collapsible) {
    // 此时TypeScript知道props属于CollapsibleStateProps,onToggle是安全可调用的
    props.onToggle();
  } else {
    // 此时props属于NonCollapsibleStateProps,onToggle是undefined,调用会直接报错
    // props.onToggle(); // ❌ TypeScript会提示错误
  }

  return <div>...</div>;
};

额外优化:让onToggle在不可折叠时可选

如果你希望当collapsible为false时,onToggle可以省略不传递(而不是必须传undefined),可以把NonCollapsibleStateProps改成这样:

type NonCollapsibleStateProps = {
  collapsible: false;
  onToggle?: undefined;
};

这样用户使用组件时,当collapsible={false},可以完全不写onToggle属性,TypeScript也不会报错。

泛型方案(可选)

如果你更倾向于用泛型来实现,也可以这样定义:

type Props<T extends boolean> = {
  collapsible: T;
  onToggle: T extends true ? () => void : undefined;
};

不过这种方式需要用户在使用组件时显式指定泛型参数(比如<MyComponent<true> collapsible={true} onToggle={() => {...}} />),不如联合类型的方式灵活,所以一般更推荐前者。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 22:52:50