Structural typing means TypeScript decides if two types fit by their shape, not by their name.
A value fits a type if it has all the properties the type requires, with compatible types. This is true even when:
- the value was never declared as that type
- the value has extra properties
So two types with different names but the same shape can be used in place of each other. Think of a job that needs "someone who can drive". Anyone with a licence fits, whatever their job title.
Excess property checks are an exception for fresh object literals. A fresh object literal is an object you write directly at the place where a type is expected. Here TypeScript reports any property the type does not declare, because it is usually a typo.
If you first store the object in a variable and then assign the variable, the check does not run. The normal structural rules apply, and the extra properties are allowed.
In short: extra properties are allowed in general, but TypeScript flags them where they are most likely a mistake.
- TypeScript decides compatibility by shape, not by the declared name.
- Extra properties are normally fine, because a subtype has more members.
- Excess property checks apply only to fresh object literals written directly where a type is expected.
- Assigning through a separate variable skips the excess property check.