It is well-known that TypeScript applies structure typing, as demonstrated in the following example:
interface Vector {
x: number;
y: number;
}
interface NamedVector {
x: number;
y: number;
name: string;
}
function calculateLength(v: Vector) {
return Math.sqrt(v.x * v.x + v.y * v.y);
}
const v: NamedVector = { x: 3, y: 4, name: 'zee' };
calculateLength(v); // compiles without errors, result is 5
This allows calculateLength
to be called with a NamedVector
because their structures are compatible.
However, when it comes to assignment, structure typing is not used anymore:
const v: Vector = { x: 3, y: 4, name: 'Zee' }; // compile error, 'name' does not exist in type 'Vector'
Based on the definition of structure typing, { x: 3, y: 4, name: 'Zee' }
should also be compatible with Vector
, so why doesn't structure typing work in this case?
Furthermore, what Utility Types can be used to describe a type that must contain both x
and y
fields along with some other fields, in order to do something like:
const v: XXX<Vector> = { x: 3, y: 4, name: 'Zee' };