TypeScript Structural Typing
Structural typing judges a value by its shape, not by a declared type name. A value fits a type when it carries at least the members that the type requires.
Extra members on a variable are accepted
The variable holds three members and the target shape needs two. The assignment succeeds because the extra member arrived through a variable.
type Point = { x: number; y: number };
const point3d = { x: 1, y: 2, z: 3 };
const point: Point = point3d;
console.log(point.x);
console.log(point.y);The same members in a fresh literal are refused
A fresh object literal is an object written directly in the assignment. The checker applies the excess property check to fresh literals and refuses the unknown member z.
type Point = { x: number; y: number };
const point: Point = { x: 1, y: 2, z: 3 };
console.log(point);Fewer parameters is assignable
The target type calls the handler with two arguments. A function that declares only the first parameter ignores the second argument and still fits.
type Handler = (id: number, labelText: string) => string;
const shortHandler: Handler = (id: number) => "id " + id;
console.log(shortHandler(7, "pen"));More parameters is refused
This function needs a second argument that the target type never supplies. The assignment fails at compile time.
type OneArg = (value: number) => string;
const twoArg: OneArg = (value: number, extra: string) => extra + value;
console.log(twoArg(1));Example
type Config = { hostName: string; port: number };
const fullConfig = { hostName: "localhost", port: 8080, debug: true };
const config: Config = fullConfig;
type Greeter = (userName: string, punctuation: string) => string;
const greet: Greeter = (userName: string) => "Hi " + userName;
console.log(config.hostName);
console.log(config.port);
console.log(greet("Ana", "!"));Key points
- An object variable with extra members is assignable to a smaller shape that it covers.
- Excess property checks apply to fresh object literals only.
- A fresh literal with an extra member is refused by an excess property error.
- A function with fewer parameters is assignable where a type supplies more arguments.
- A function needing more parameters than the type supplies is refused.
In this example, a variable with an extra debug member fits the smaller Config shape, and a one-parameter function fits a greeter type that supplies two arguments.
Note
Passing a variable first is the standard way to keep extra data while fitting a smaller shape.
Try it Yourself
Edit the code, then press Run.
Running is simulated ยท TypeScript Playground
Exercise
Why does an extra member pass through a variable but fail in a fresh object literal?