为何空值合并运算符会移除Record联合类型中的某一分支?
为什么空值合并运算符会移除联合类型中的分支?
这个问题的核心是TypeScript对子类型联合的自动简化逻辑。
先看你的代码片段:
declare const thing: | { id: number; version: number; label: string } | { label: string } | undefined; // 实际类型为 {label: string} | null,而非预期的多分支联合 const thingWithCoallesce = thing ?? null;
这里{ id: number; version: number; label: string }是{ label: string }的子类型——前者完全包含后者的所有属性且无冲突。当你使用??运算符时,TypeScript会自动合并这种存在包含关系的联合类型分支,只保留更宽泛的那个类型(也就是{ label: string })。因为从类型兼容性角度,任何属于子类型的值都可以赋值给父类型变量,保留父类型既不丢失安全性,还能简化类型结构。
如果想强制保留原联合类型结构,有两种常见方式:
- 用类型断言手动指定类型:
const thingWithCoallesce = thing ?? null as | { id: number; version: number; label: string } | { label: string } | null;
- 调整类型定义,让两个对象类型不存在子类型关系(比如给第二个类型添加冲突的可选属性):
declare const thing: | { id: number; version: number; label: string } | { label: string; id?: never } | undefined; const thingWithCoallesce = thing ?? null; // 此时类型为 { id: number; version: number; label: string } | { label: string; id?: never } | null
内容的提问来源于stack exchange,提问作者Jonathan Raoult
相关产品推荐
相关产品推荐

