BeCuriouzLearn something new every day
Structural Typing: If It Fits the Shape, It Fits
💡 TypeScript matches types by their structure, not their name — any object with the required shape fits, regardless of how it was declared.
In many languages, a value only matches a type if it was declared with that type's name. TypeScript works differently: it uses structural typing, meaning compatibility is decided by an object's shape — the properties and methods it actually has — not by the name it was created under. This is the programmer's version of the old saying: if it walks like a duck and quacks like a duck, it's a duck. Hence the nickname duck typing.
Recall the interface from earlier cards. When you write a function that expects an interface, TypeScript doesn't ask "was this object built from that interface?" It asks "does this object have at least the required members?" If yes, it's accepted — even if the two types were never linked by name.
interface Point {
x: number;
y: number;
}
function printPoint(p: Point) {
console.log(`${p.x}, ${p.y}`);
}
// Never declared as a Point, but its shape matches:
const dot = { x: 3, y: 4, color: "red" };
printPoint(dot); // ✅ works — extra 'color' is fineThe object dot was never labeled a Point, yet it's accepted because it has an x and a y that are numbers. Extra properties are allowed when passing an existing variable — the shape only needs to include everything required. (A subtle exception: an object literal passed directly triggers excess property checks, flagging unexpected fields to catch typos.) This shape-based flexibility is what makes TypeScript feel lightweight while staying safe.