如何通过keyof理解TypeScript交叉类型的赋值矛盾?
关于TypeScript交叉类型与keyof的疑问解答
先看你给出的代码示例:
interface Person { name: string; } interface Lifespan { birth: Date; death: Date; } type PersonSpan = Person & Lifespan; type K = keyof PersonSpan; // type K = "name" | "birth" | "death" let prop: K = "name"; // ok let obj: PersonSpan = { // compile error, missing birth and death properties name: "John Smith" }
你这里的核心误区是把keyof的作用和交叉类型的类型约束搞混了:
keyof PersonSpan得到的"name" | "birth" | "death",只是列举出了PersonSpan类型包含的所有键,但这并不意味着只要拥有其中一个键的对象就符合PersonSpan类型。联合类型的变量(比如prop)只需要取联合中的任意一个值就合法,但类型本身的约束是另一回事。- 交叉类型
Person & Lifespan的本质是同时满足两个接口的全部要求,也就是说,一个PersonSpan类型的对象必须同时拥有Person的name属性,以及Lifespan的birth和death属性,三者缺一不可。这是TypeScript结构类型系统的规则:要赋值给一个复合类型,必须满足该类型的所有属性约束。
简单来说,keyof只是告诉你这个类型有哪些键,但类型本身要求你必须拥有所有这些键对应的属性,而不是只拥有其中一个。比如你不能只给a属性就把对象赋值给{a: number} & {b: string}类型,道理是完全一样的。
内容的提问来源于stack exchange,提问作者lch
相关产品推荐
相关产品推荐

