The satisfies operator
Introduced in TypeScript 4.9, satisfies validates that a value matches a type without widening the inferred type.
Problem with regular annotation
ts
type Colors = 'red' | 'green' | 'blue';
type Palette = Record<Colors, string | number[]>;
// with annotation - TypeScript widens to string | number[]
const palette: Palette = {
red: '#ff0000',
green: [0, 255, 0],
blue: '#0000ff',
};
palette.red.toUpperCase(); // Error - might be number[]With satisfies - type is preserved
ts
const palette = {
red: '#ff0000',
green: [0, 255, 0],
blue: '#0000ff',
} satisfies Palette;
palette.red.toUpperCase(); // ok - TypeScript knows it's string
palette.green.map(v => v * 2); // ok - TypeScript knows it's number[]Comparison
: Type annotation | satisfies Type | |
|---|---|---|
| Validates against type | Yes | Yes |
| Keeps the narrower inferred type | No | Yes |
| Inferred type | Widened to Type | Stays specific |
Another use case
ts
const config = {
port: 3000,
host: 'localhost',
} satisfies Partial<ServerConfig>;
// config.port is still number, not number | undefined
satisfiesis ideal for config objects and constants where you want validation but need to keep the precise inferred type.
updated
did you know it?