类型兼容性理解问题



在此视频中https://youtu.be/wD5WGkOEJRs?t=65显示的第一个例子是:

let x : { name: string };
let y : { name: string, age: number };
let z : any = {
name: "Fred",
lastName: "Flintstone",
age: 50000
};
x = { name: "Ted" };
y = { name: "Ted", age: 45 };
x = z; // OK
y = z; // OK
x = y; // OK
//y = x; // Error!

我重复了上一个案例中的错误,但我不明白为什么会出现这种错误。错误消息为:

属性"age"在类型"{name:string;}"中丢失,但在类型"{name:string;age:number;}("中是必需的。

然而,就在导致错误的最后一次赋值之前,两个变量都包含相同的内容,即:

{
"name": "Fred",
"lastName": "Flintstone",
"age": 50000
}

由于z之前的作业。如果类型不同,为什么这些分配是可能的?

不幸的是,一旦TypeScript为变量分配了一个类型(这里是用let x : { name: string }显式执行的(,它以后就不会重新计算该类型,即使您给它传递了一个具有更多属性的值,因此也可以与另一个类型兼容。

因此,当您执行x = z时,x的类型仍然是您在一开始指定的类型,而不是z的类型。

(顺便说一句,由于https://www.typescriptlang.org/docs/handbook/interfaces.html#excess-属性检查,如前面的答案所解释的(

如果你有一个代码完成的IDE(通常是VSCode IntelliSense(,你可以验证它:在上面的重新分配之后,看看IDE作为x的可用成员提供了什么:应该只有";name";,尽管对于开发者来说很明显;lastName"以及";年龄";。

因此TypeScript抱怨y = x

这可能是一个要转换的用例,因为在这种情况下,开发人员比编译器更清楚。

y = x as typeof z;

最新更新