Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The satisfies operator is a type-checking mechanism that validates an expression against a specific type without altering or widening the compiler’s inferred type for that expression. It ensures structural compliance while preserving the most specific literal types and property shapes of the assigned value.
expression satisfies Type

Mechanics and Type System Behavior

To understand satisfies, it must be contrasted with standard type annotations (:) and type assertions (as).

1. Prevention of Type Widening (vs. Type Annotations)

When you use a type annotation, TypeScript upcasts the assigned value to the specified type. This results in type widening, where the compiler forgets the specific literal values of the object in favor of the broader union or interface definition.
type Color = "red" | "green" | "blue";
type RGB = [number, number, number];
type Palette = Record<string, Color | RGB>;

// Using Type Annotation (Widening occurs)
const annotatedPalette: Palette = {
    primary: "red",
    secondary: [0, 255, 0]
};

// The compiler types `annotatedPalette.primary` as `Color | RGB`.
// String methods like .toUpperCase() will fail because it might be an array.
The satisfies operator applies contextual typing to validate the shape, but instructs the compiler to retain the exact inferred type of the expression.
// Using satisfies (Narrow types retained)
const satisfiedPalette = {
    primary: "red",
    secondary: [0, 255, 0]
} satisfies Palette;

// The compiler types `satisfiedPalette.primary` exactly as `"red"`.
// The compiler types `satisfiedPalette.secondary` exactly as `[number, number, number]`.

2. Type Safety and Excess Property Checks (vs. Type Assertions)

Type assertions (as) override the compiler’s type inference. They bypass standard type checking, allowing you to assign objects missing required properties or containing invalid types, which can lead to runtime errors.
type User = { id: number; name: string };

// Type Assertion (Unsafe: bypasses checks)
const userA = { id: 1 } as User; // No error, despite missing 'name'
The satisfies operator is strictly a validation step. It enforces excess property checks and required property checks on object literals, failing compilation if the expression does not strictly satisfy the target type.
// satisfies (Safe: enforces structural contract)
const userB = { id: 1 } satisfies User; 
// Error: Property 'name' is missing in type '{ id: number; }' but required in type 'User'.

const userC = { id: 2, name: "Bob", age: 30 } satisfies User;
// Error: Object literal may only specify known properties, and 'age' does not exist in type 'User'.

Key Characteristics

  • Zero Runtime Cost: Like type annotations and assertions, satisfies is completely erased during compilation to JavaScript.
  • Property Retention: If an object literal contains properties that match an index signature in the target type, satisfies retains knowledge of those specific keys, whereas a type annotation would obscure them behind the generic index signature.
  • Contextual Inference: It pushes the target type down into the expression to provide contextual typing (e.g., inferring parameter types in inline callbacks) before locking in the final, narrowed type.
Master TypeScript with Deep Grasping Methodology!Learn More