TYPESCRIPT

TypeScript satisfies Operator: Purpose, Usage, and Examples

The satisfies operator, introduced in TypeScript 4.9, lets you check that a value conforms to a particular type without changing its inferred structure. This means you get the benefits of structural type validation without losing the narrow type information that TypeScript infers from the original value.

Instead of forcing a value into a new type, the satisfies operator validates that the value matches the expected shape while keeping its most precise, specific type.


What Is the satisfies Operator?

The satisfies operator ensures that an expression is assignable to a given type, without modifying or transforming it.

Syntax:

const variable = expression satisfies TargetType;

Here, TypeScript checks that expression matches TargetType, but infers the type of variable directly from the expression, not from the target type.


Preserving Narrow Types

One of the biggest advantages of using satisfies is that it retains literal types, enabling more specific and accurate type behavior.

const directions = ["north", "south", "east", "west"] as const;

const obj = {
  north: "up",
  south: "down",
  east: "right",
  west: "left",
} satisfies Record<(typeof directions)[number], string>;

In this example, TypeScript checks that the object covers all required keys but preserves the literal types of each value.


Validating Object Structures

The operator helps ensure that an object correctly conforms to an interface or type definition.

type User = {
  id: number;
  name: string;
};

const user = {
  id: 1,
  name: "Alice",
} satisfies User;

If you omit or mistype a property, TypeScript will issue an error during compilation.


Ensuring Complete Mappings

You can validate full key coverage when working with maps or configuration objects.

const statuses = {
  idle: "Idle",
  loading: "Loading",
  success: "Success",
  error: "Error",
} satisfies Record<"idle" | "loading" | "success" | "error", string>;

This guarantees that all required keys are included—no more, no less.


Using with as const

The as const assertion freezes values to their literal types. Combining it with satisfies gives you both structural validation and type specificity.

const theme = {
  light: "#FFF",
  dark: "#000",
} as const satisfies Record<string, string>;

This approach keeps "light" and "dark" as literal values while ensuring they’re valid strings in a broader context.


Array and Tuple Validation

Satisfies also works well when mapping values from fixed arrays or tuples.

const roles = ["admin", "user", "guest"] as const;

const permissions = {
  admin: true,
  user: true,
  guest: false,
} satisfies Record<(typeof roles)[number], boolean>;

This ensures that every role has a defined permission and avoids accidental omissions.


Difference from Type Assertions

Unlike type assertions (e.g., as Type), satisfies doesn’t silence type errors. Instead, it verifies correctness without overriding the inferred type.

const invalid = { x: 1 } as { x: number; y: number }; // No error

const validated = { x: 1 } satisfies { x: number; y: number }; // Error: 'y' is missing

This helps prevent logical errors that could be introduced by overconfident casting.


Difference from Type Annotations

Annotations like const obj: Type = value force the compiler to adopt the annotated type, often widening literal values. In contrast, satisfies keeps the original narrow values intact.

const label = {
  status: "active",
} satisfies { status: string }; // status is still "active"

const typed: { status: string } = {
  status: "active",
}; // status is now widened to string

Preserving narrow values helps with strict equality checks and discriminated unions.


Validating Config Objects

Developers often use satisfies when creating configuration files or static definitions to ensure the data structure is safe.

const config = {
  baseUrl: "https://api.example.com",
  retry: 3,
} satisfies {
  baseUrl: string;
  retry: number;
};

This avoids over-annotation while ensuring that the config meets required constraints.


Mapping Enum Keys

Pairing enums with value maps is a common pattern, and satisfies ensures consistency between enum values and keys.

enum Status {
  Open = "open",
  Closed = "closed",
}

const messages = {
  open: "Case is open",
  closed: "Case is closed",
} satisfies Record<Status, string>;

This ensures your mapping is complete and accurately typed, which is especially useful in apps with multiple UI states or translations.


Why Use satisfies?

  • Keeps literal values intact — useful for narrowing types without widening.
  • Improves developer experience — better autocompletion and more helpful compiler errors.
  • Reduces unnecessary verbosity — avoids extra type annotations that obscure intent.
  • Boosts reliability in static config — catch shape mismatches at compile time.
  • Integrates well with as const — enables expressive and safe type modeling.

Limitations

Despite its usefulness, the satisfies operator has a few constraints:

  • Only works at compile time — it doesn’t affect how the code behaves at runtime.
  • Not usable in expressions — you can only use it in declarations.
  • Doesn’t narrow types at runtime — still need type guards for runtime validation.
  • Requires clear shape — won’t infer types through complex logic or side effects.

Best Practices

  • Combine with as const to keep both structure and literal precision.
  • Use it instead of assertions or annotations for validating static data.
  • Apply it in map objects, enums, or static configurations to catch errors early.
  • Don’t use it for values that require runtime validation or transformation.

Summary

The satisfies operator adds another layer of type safety to TypeScript by confirming structural compatibility without discarding inferred details. It helps you build safer configurations, enforce object structures, and validate mappings—all without resorting to type assertions or verbose annotations.

By adopting this operator in projects with strict typing needs or static data structures, you can maintain high code quality while benefiting from smarter, more expressive type inference.

Learn TypeScript for Free
Start learning now
button icon
To advance beyond this tutorial and learn TypeScript by doing, try the interactive experience of Mimo. Whether you're starting from scratch or brushing up your coding skills, Mimo helps you take your coding journey above and beyond.

Sign up or download Mimo from the App Store or Google Play to enhance your programming skills and prepare for a career in tech.

You can code, too.

© 2025 Mimo GmbH

Reach your coding goals faster