satisfies Operator
| Since: | TypeScript 4.9(2022) |
|---|
The satisfies operator validates that a value matches a specific type while preserving the inferred type as-is. When a type annotation (colon syntax) would widen the type, satisfies lets you perform type checking while keeping the more precise type information. It was introduced in TypeScript 4.9.
Syntax
const value = expression satisfies Type;
Comparison with as and type annotations
| Syntax | Type check | Inferred type |
|---|---|---|
| const x: Type = value | Yes | Type (widened to the annotation) |
| const x = value as Type | No (forced cast) | Type (unsafe) |
| const x = value satisfies Type | Yes | The actual type of value (narrow type is preserved) |
Sample code
type Config = Record<string, string | string[]>;
// Using : Config annotation
const config1: Config = {
port: '3000',
hosts: ['localhost', 'example.com'],
};
// config1.port is recognized as string | string[]
// config1.port.toUpperCase(); // Error: toUpperCase does not exist on string | string[]
// Using satisfies
const config2 = {
port: '3000',
hosts: ['localhost', 'example.com'],
} satisfies Config;
// config2.port is preserved as string
console.log(config2.port.toUpperCase()); // OK: '3000' → '3000'
// config2.hosts is preserved as string[]
console.log(config2.hosts.join(', ')); // OK
// Type checking still works (incorrect values cause errors)
const bad = {
port: 3000, // Error: number is not assignable to string | string[]
} satisfies Config;
// Color palette example
type Color = { r: number; g: number; b: number } | string;
const palette = {
red: { r: 255, g: 0, b: 0 },
blue: '#0000ff',
} satisfies Record<string, Color>;
// red is preserved as an object type, blue is preserved as string
console.log(palette.red.r); // OK: 255
console.log(palette.blue.toUpperCase()); // OK: '#0000FF'
Overview
satisfies shines in cases where you want type checking but do not want to lose the precise inferred type of each property. Using a type annotation (:) fixes the variable's type to the annotated type, so the detailed per-property type information is lost.
A type assertion with as skips type checking entirely, so an incorrect type will not produce an error. satisfies, on the other hand, performs type checking while preserving the original inferred type — combining the strengths of both approaches.
It is especially useful when working with object literals whose properties have different types, such as configuration objects, color palettes, and route tables.
If you find any errors or copyright issues, please contact us.