gotchatypescriptModeratepending
Gotcha: TypeScript satisfies operator vs type annotation
Viewed 0 times
satisfiestype-annotationinferencewideningliteral-type
Error Messages
Problem
Type annotations (: Type) widen the inferred type, losing specific literal types. Need to validate a type without widening.
Solution
Use 'satisfies' to validate without widening:
type Colors = Record<string, [number, number, number]>;
// With type annotation - loses specific keys:
const colors: Colors = {
red: [255, 0, 0],
green: [0, 255, 0],
};
colors.red; // [number, number, number] - OK
colors.blue; // No error! string index allows any key
// With satisfies - keeps specific keys:
const colors2 = {
red: [255, 0, 0],
green: [0, 255, 0],
} satisfies Colors;
colors2.red; // [number, number, number] - OK
colors2.blue; // Error! Property 'blue' doesn't exist
// More examples:
type Route = { path: string; exact?: boolean };
const routes = {
home: { path: '/', exact: true },
about: { path: '/about' },
} satisfies Record<string, Route>;
// routes.home.path is string (not widened to Route)
// routes.home.exact is true (not boolean | undefined)
// routes.missing would be an error
// Use cases:
// 1. Config objects: validate shape, keep literal types
// 2. Enum-like objects: validate values, keep specific keys
// 3. Theme objects: validate structure, keep autocomplete
type Colors = Record<string, [number, number, number]>;
// With type annotation - loses specific keys:
const colors: Colors = {
red: [255, 0, 0],
green: [0, 255, 0],
};
colors.red; // [number, number, number] - OK
colors.blue; // No error! string index allows any key
// With satisfies - keeps specific keys:
const colors2 = {
red: [255, 0, 0],
green: [0, 255, 0],
} satisfies Colors;
colors2.red; // [number, number, number] - OK
colors2.blue; // Error! Property 'blue' doesn't exist
// More examples:
type Route = { path: string; exact?: boolean };
const routes = {
home: { path: '/', exact: true },
about: { path: '/about' },
} satisfies Record<string, Route>;
// routes.home.path is string (not widened to Route)
// routes.home.exact is true (not boolean | undefined)
// routes.missing would be an error
// Use cases:
// 1. Config objects: validate shape, keep literal types
// 2. Enum-like objects: validate values, keep specific keys
// 3. Theme objects: validate structure, keep autocomplete
Why
satisfies validates the type at the assignment site while preserving the narrowest possible inferred type, giving you both safety and precision.
Revisions (0)
No revisions yet.