- Published on
Understanding the satisfies Operator in TypeScript
- Authors

- Name
- Mehdi Akiki
The satisfies operator in TypeScript is a relatively new addition that combines the power of type checking with preserving the literal type information of an object. This feature is particularly useful in scenarios where you need to ensure that an object conforms to a specific type while retaining additional property type information for later use. In this article, we’ll explore how the satisfies operator works, its benefits, and how it compares to other approaches like as or explicit typing.
Basics of the satisfies Operator
Let’s start with a simple example:
type Config = {
theme: "dark" | "light";
};
const appConfig = {
theme: "dark",
debug: true,
} satisfies Config;
This code will throw an error:
Object literal may only specify known properties, and 'debug' does not exist in type 'Config'.
Why Does This Happen?
The satisfies operator enforces strict compatibility with the provided type (Config), ensuring that:
- The object has exactly the properties defined in the type.
- No extra properties are added unless explicitly accounted for.
In this example, debug is not a property of Config, so TypeScript raises an error.
Fixing the Issue
To include additional properties like debug while ensuring the object still satisfies the Config type, you can use one of the following approaches:
1. Type Intersection
Extend the Config type using a union with a more flexible type:
type Config = {
theme: "dark" | "light";
};
const appConfig = {
theme: "dark",
debug: true,
} satisfies Config & Record<string, unknown>; // ✅ No error
Here, Record<string, unknown> allows additional properties without violating the Config structure.
2. Separate the Validation
Define the object first, then validate it separately using satisfies:
type Config = {
theme: "dark" | "light";
};
const appConfig = {
theme: "dark",
debug: true,
};
const validatedConfig = appConfig satisfies Config; // ✅ No error
This approach retains extra properties in appConfig while ensuring validatedConfig conforms to Config.
Key Benefits of satisfies
Preserves Literal Type Information Unlike explicit typing or type assertions,
satisfiesretains the literal type of object properties:const favoriteColors = { red: "yes", green: false, blue: "kinda", } satisfies Record<"red" | "green" | "blue", unknown>; favoriteColors.red.toUpperCase(); // ✅ OK (string) favoriteColors.green.toUpperCase(); // ❌ Error (boolean)Without
satisfies, TypeScript would generalizefavoriteColors.redandfavoriteColors.greentounknown, preventing useful operations like callingtoUpperCase()on the string.Type Safety Without Casting The
askeyword bypasses type safety, potentially introducing runtime errors. Thesatisfiesoperator enforces type correctness without overriding the type system.const config = { theme: "dark", debug: true, } as Config; // ✅ No compile error, but risky console.log(config.debug.toFixed(2)); // ❌ Runtime error: debug is not a numberUseful for Frameworks Frameworks like Vue or React that use object literals extensively can benefit from
satisfiesto validate configurations while preserving type inference.
Comparison: satisfies vs Explicit Typing
Consider the following example:
type Colors = "red" | "green" | "blue";
const favoriteColors: Record<Colors, unknown> = {
red: "yes",
green: false,
blue: "kinda",
};
favoriteColors.red.toUpperCase(); // ❌ Error: Type is unknown
Here, explicit typing with Record<Colors, unknown> forces all values to be unknown, losing the specific type information of red, green, and blue.
With satisfies:
const favoriteColors = {
red: "yes",
green: false,
blue: "kinda",
} satisfies Record<Colors, unknown>;
favoriteColors.red.toUpperCase(); // ✅ OK
favoriteColors.green.toUpperCase(); // ❌ Error: green is a boolean
The satisfies operator retains the literal type of each value while ensuring the object conforms to the Record<Colors, unknown> type.
Summary
The satisfies operator is a powerful tool that ensures an object conforms to a specific type while preserving the inferred types of its properties. It’s particularly useful in scenarios where:
- You need to validate objects with strict type requirements.
- You want to retain detailed type information for further operations.
- You aim to enhance type safety without resorting to type assertions.
Use the satisfies operator to make your TypeScript code safer, more expressive, and easier to maintain!
I build and scale reliable production systems. Open to full-time and freelance work with U.S.-based teams that value ownership and execution.
Got something in mind?
Book a Discovery Call