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

TypeScript带可选判别式的区分联合是否允许无效值赋值?

关于TypeScript联合类型与React Props的问题解答

首先看你给出的代码:

type P =
  | { foo: boolean; bar?: undefined }
  | { foo: boolean; bar: boolean; baz: boolean };
const p: P = { foo: true, baz: true };

这段代码能通过TypeScript检查,和你的预期不符,原因在于TypeScript的结构类型检查规则:对象只要匹配联合类型中任意一个分支的必填字段,就可以赋值。第一个分支{ foo: boolean; bar?: undefined }只要求foo是布尔值,bar可选(甚至可以完全不写),而额外的baz字段会被TypeScript忽略,所以{ foo: true, baz: true }能匹配第一个分支,自然不会报错。

要实现你预期的“只有两种有效值”,可以通过给分支添加禁止额外字段的约束来修正类型:

type P =
  | { foo: boolean; bar?: undefined; baz?: never }
  | { foo: boolean; bar: boolean; baz: boolean };

这里第一个分支把baz设为never类型且可选,意味着这个分支下baz不能有任何有效值(甚至不能出现在对象中),这样{ foo: true, baz: true }就会触发类型错误,完全符合你的预期。

至于你问的区分联合是否必须包含所有字段?答案是不需要,但要让TypeScript能明确区分不同分支,最稳妥且常用的方式是使用辨别符字段——也就是在所有联合分支中定义一个同名但类型不同的字段,比如:

type Props =
  | { foo: boolean; type: "simple" }
  | { foo: boolean; type: "complex"; bar: boolean; baz: boolean };

在React组件中,你可以通过props.type来判断当前属于哪个分支,TypeScript会自动帮你缩小类型范围,访问对应分支的专属字段时不会出现类型错误,这也是React props区分联合的标准写法。

如果不想用辨别符,也可以通过约束字段的互斥性来实现,但这种写法相对繁琐,远不如辨别符直观好维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 04:50:13