Reputation: 143
In this video https://youtu.be/wD5WGkOEJRs?t=65 the first example that is shown is:
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!
I reproduced the error in the last case, but I don't understand why it arises. The error message is:
Property 'age' is missing in type '{ name: string; }' but required in type '{ name: string; age: number; }'.
However right before the last assignment that causes the error, both variables hold the same content, namely:
{
"name": "Fred",
"lastName": "Flintstone",
"age": 50000
}
due to the assignments from z before. Why were those assignments possible if the types are different?
Upvotes: 0
Views: 51
Reputation: 53185
Unfortunately, once TypeScript has assigned a type to a variable (here you do it explicitly with let x : { name: string }
), it does not re-evaluate that type later on, even if you pass it a value that has more properties, hence could be compatible with another type as well.
Therefore when you do x = z
, x's type is still what you have specified at the very beginning, not z's type.
(BTW that assignment is allowed thanks to https://www.typescriptlang.org/docs/handbook/interfaces.html#excess-property-checks, as explained by previous answers)
You can verify it if you have an IDE with code completion (typically VSCode IntelliSense): after above reassignment, see what the IDE offers as available members of x
: there should be only "name", even though it is obvious for the developer that we have now also "lastName" and "age".
Hence TypeScript complains for y = x
.
This could be a use case to cast, since the developer knows better than the compiler in this very situation.
y = x as typeof z;
Upvotes: 1