为什么Typescript允许将`{a:1,b:2}`赋给类型{{a:any} | {b:任何}`?

时间:2019-12-23 23:33:50

标签: typescript

考虑以下代码:

let foo: {a: any} | {b: any} = {a: 1, b: 2};

我希望TypeScript拒绝此代码,因为此联合类型表示第一类型或第二类型,并且该值不可分配给任何一个,因此类型检查应拒绝它。但实际上它过去了,为什么?

(对于背景来说,上述类型旨在作为“此属性或该属性,但不能同时选择这两种类型。请参阅Typescript Interface - Possible to make "one or the other" properties required?

1 个答案:

答案 0 :(得分:5)

根据the blog post introducing union excess property checking in TypeScript 3.5,TypeScript将检查它是否属于至少一种类型

  

在TypeScript 3.4及更早版本中,某些多余的属性在确实不应该存在的情况下被允许。例如,TypeScript 3.4允许对象文字中使用不正确的name属性,即使其类型在Point和Label之间不匹配。

     
type Point = {
    x: number;
    y: number;
};

type Label = {
    name: string;
};

const thing: Point | Label = {
    x: 0,
    y: 0,
    name: true // uh-oh!
};
     

以前,不区分大小写的联合不会对其成员执行任何多余的属性检查,结果,键入不正确的名称属性就会溜走。

     

在TypeScript 3.5中,类型检查器至少验证所有提供的属性都属于某个联合成员并具有适当的类型,这意味着上面的示例正确地发出了错误。

博客文章继续明确地将重叠描述为有效:

  

请注意,只要属性类型有效,仍然允许部分重叠。

     
const pl: Point | Label = {
    x: 0,
    y: 0,
    name: "origin" // okay
};

基于短语“所有提供的属性属于某个工会成员,并且具有适当的类型”,看来多余的属性检查器无法将这些属性视为互斥的。 / p>