Skip to main content

Satisfies

Introduced in TypeScript 4.9, the satisfies operator fixes a major flaw with explicit type annotations: the loss of literal type information.

The problem with explicit annotations

When you explicitly annotate a variable, TypeScript widens the assigned value to exactly match that annotation.

type Colors = Record<string, string | number[]>;

const theme: Colors = {
primary: "blue",
secondary: [255, 0, 0]
};

// Error: Property 'toUpperCase' does not exist on type 'string | number[]'
// theme.primary.toUpperCase();

Because theme is annotated as Colors, TypeScript forgets that primary was specifically a string and secondary was an array. It only knows they are string | number[].

The solution: satisfies

The satisfies operator allows you to validate that an object matches a shape, without widening its inferred literal types.

const safeTheme = {
primary: "blue",
secondary: [255, 0, 0]
} satisfies Colors;

// Valid! TS remembers this is a string
safeTheme.primary.toUpperCase();

// Valid! TS remembers this is an array
safeTheme.secondary.push(0);

When to use satisfies

Use satisfies primarily for configuration objects, theme definitions, or route maps. Anywhere you want to guarantee that a massive object conforms to a strict interface, but you still want the precise autocomplete and literal type inference of its exact values.

satisfies validates that a value matches a type, but preserves the most specific inferred type of the value instead of widening it to the interface.