dan-ros
dan-ros

Reputation: 143

Type Compatibility understanding issues

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

Answers (1)

ghybs
ghybs

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

Related Questions