为何TypeScript使用‘或’运算符合并类型时出现异常报错?
这不是TypeScript Bug!是联合类型的设计规则导致的
先贴出你的代码:
type A = { a: number; } // Uncommenting the line below and commenting the line above removes the error // type A = { a: number; b: string; } type B = { b: string; } type AB_ = A | B const c: AB_ = { a: 1, b: '2' }; // Why no error here? c.a = 2; // Error: "Property 'a' does not exist on type 'AB_'. Property 'a' does not exist on type 'B'."
下面拆解这几个怪异现象的原因:
1. 赋值时不报错的逻辑
TypeScript判断对象字面量能否赋值给联合类型时,规则是:只要字面量能被联合类型里至少一个成员完全兼容,就允许赋值。
这里的{a:1, b:'2'}完全符合A的结构(A只要求有a,额外的b属性不会触发严格的额外属性检查——这是联合类型赋值时的特殊规则),所以TypeScript认为这个对象可以归为A类型,自然能赋值给AB_。
2. 访问c.a报错的逻辑
当你访问联合类型变量的属性时,规则完全不同:只有所有联合成员都拥有的属性,才能直接访问。AB_是A | B,B没有a属性,TypeScript无法确定c到底是A还是B——万一它是B,访问a就会在运行时出错,所以直接报错阻止你这么做。
3. 修改A包含b后错误消失的逻辑
把A改成{a: number; b: string}后,AB_变成A | B,但你赋值的{a:1, b:'2'}明确符合A的完整结构,TypeScript会自动做类型窄化:把c的类型从宽泛的AB_缩小为具体的A,这时候访问a自然就没问题了。
另外此时A是B的超集,TypeScript也会默认把这种联合类型的检查逻辑放宽,进一步确保属性访问的合法性。
内容的提问来源于stack exchange,提问作者Floris
相关产品推荐
相关产品推荐

