【发布时间】:2020-07-11 09:47:04
【问题描述】:
我正在尝试更深入地了解 Typescript 类型,但我发现以下行为令人困惑:
interface Person {
name: string;
}
interface Lifespan {
birth: number;
death?: number;
}
let k: keyof (Person | Lifespan); //k is never
let test1: Person | Lifespan = { randomKey: 123 }; //I understand the error: Object literal may only specify known properties (because keyof is never)
let test2: Person | Lifespan = { name: "A Name" }; //No error given which is confusing, where does test2 get "name" property from?
这是否是一种疏忽/试图以某种方式提供帮助 - 通过过多的属性检查?当 union 的 keyof 为 never 时,我不明白为什么 TypeScript 认为“name”在这里有特殊含义。
【问题讨论】:
-
这是一个联合类型 -
test2可以是Person或Lifespan(所以{ name: "A Name" }在这里有效)。keyof (Person | Lifespan)是never因为它们没有共同的属性 -
感谢您的回答,但我认为在 TS 类型系统的深处将联合视为 OR 有点简单化。它也可以是“两者”,所以
let test2: Person | Lifespan = { name: "asd", birth: 3 };也是有效的(合并两者的键),所以 TS 识别出Person | Lifespan组合 可以 有名字、出生、死亡,但是如果我们查询那个的键在类型系统中键入,它永远不会提供 - 但是过多的属性检查以某种方式知道这些键 - 这是我觉得令人困惑的地方。 -
不,联合是
or。相关stackoverflow.com/questions/38628115/…。更多信息在这里typescriptlang.org/docs/handbook/unions-and-intersections.html。两者都是交集。关于let test2: Person | Lifespan = { name: "asd", birth: 3 };- 由于结构类型系统,它是允许的。 -
这是我试图建立直觉的“结构类型系统”。这就是为什么我要追求明显的不一致之处,因为我相信它们暴露了我直觉中的漏洞。当我看到
|时,我没有想到“或”,而是想到了集合论,因为它更适合 TS 解释事物的方式。例如type X = unknown | number;是未知的,而不是unknown OR number,因为未知集消耗数字。但是,对于对象属性,我的设置类比和您的 OR 类比都不起作用。 “因为 STS 才允许这样做”有点矫揉造作——无意冒犯。 -
如果
T可分配给U的至少一个组成部分,则类型T可分配给联合类型U。回到你的例子 -{ name: "asd", birth: 3 }可分配给Person和Lifespan希望有帮助
标签: typescript