晓之蛇
2024-01-03 16:55
老师您好:
联合类型产生的新类型只会有共同拥有的属性,例如下面代码:
interface EnglishCourse { name: string, desc: string } interface MathCourse { name: number, price: number } // 联合类型 type Course2 = EnglishCourse | MathCourse;
结果:联合类型Course2打点只有name属性
但是联合类型还是可以声明desc属性,这是什么原因?
这是两种安全策略的问题,分为类型匹配和属性访问限制。
类型匹配:在你的代码中,变量 c2
被定义为 Course2
类型,这是 EnglishCourse | MathCourse
的联合类型。变量 c2 的结构 { name: 'a', desc: 'abc' }
符合 EnglishCourse
接口的定义(因为 EnglishCourse
有 name
和 desc
两个属性),所以 TypeScript 认为这是一个有效的赋值。
接下来,关于为什么你不能直接访问 c2.desc:
属性访问限制:尽管变量 c2
在定义时没有报错,但当你尝试访问 c2
的属性时,TypeScript 变得更加严格。在使用联合类型时,你只能访问所有类型共有的属性。由于 EnglishCourse
和 MathCourse
没有共有的属性(它们的 name
属性类型不同),直接访问 c2.desc
会导致错误。这是因为在不确定
c2
究竟是哪个类型的情况下,直接访问可能不存在的属性是不安全的。
因此,虽然在定义变量时 TypeScript 允许 c2 匹配 MathCourse 类型,但在后续访问属性时,由于 c2 可能是 EnglishCourse 或 MathCourse,直接访问特定于其中一种类型的属性(如 desc)会导致错误。要安全地访问这些属性,你需要使用类型守卫(如类型断言或 in 关键字检查)来确定 c2 的确切类型。
这两个方面并不矛盾,而是反映了 TypeScript 在不同场景下的类型安全策略:一方面,在赋值时允许某种程度的灵活性;另一方面,访问属性时则需要更严格的类型确定性。
联和行(深圳)贸易有限公司(Liow&Co.)是华润集团旗下跨境(深圳)贸易有限公司,是深圳规模最大、实力最雄厚的跨境贸易企业--华润(集团)有限公司旗下一级利润中心。
TypeScript极速入门
3764 学习 · 3 问题