The code below outputs an error as it should:
const a = { a: 1 }
const b: typeof a = { a: 2, b: 3 }
// Error: Type '{ a: number; b: number; }' is not assignable to type '{ a: number; }'.
But this piece of code does not output an error:
const a = { a: 1 }
const b = { a: 2, c: 3 }
const c: typeof a = b
What is the problem with the second code block? And is there a way to enforce type checks there?
CodePudding user response:
It's by design, the type of a
is {a: number}
which means that it's an object with at least the property a
with type number
, and possibly any other properties. Typescript doesn't have a concept of closed object type where other properties wouldn't be allowed. So b
is perfectly valid as a member of type {a: number}
.
Now the reason why it does error in the first case is due to something called "excess property check". It's a check that only applies when assigning an object literal directly to a type, in such cases it does warn about additional properties because they are most likely errors. But this check doesn't apply when assigning the object literal to an intermediate variable first.
CodePudding user response:
TS
uses structural typing and not nominal typing. This means that if an object has enough structure then it is allowed.
This leads to the fact that you can have more properties on an object as long as you match name/types for the existing ones.
When doing an object literal assignment TS
does a stricter check and doesn't allow for extra properties.
This is a bit inconsistent, but it's by design.