Operators
satisfies
Checks a value against a type without widening it to that type.
What it is
Added in 4.9 to solve a real dilemma: annotating a constant gets it checked but throws away everything specific about it, while leaving it unannotated keeps the detail and checks nothing. `satisfies` does both — the constraint is enforced and the inferred type is the narrow one you actually wrote.
Examples
typeof routes→{ readonly home: "/"; readonly about: "/about"; }typeof widened→{ [x: string]: string; }The annotation collapses to a bare index signature — the constraint was checked and every literal thrown away doing it. That loss is what `satisfies` exists to prevent.
keyof typeof routes
→"home" | "about"
Each resolved type above was printed by TypeScript 5.9.3, not written by hand.
What it does not do
- It does not change the value or the emitted JavaScript. Like every type-level construct it is erased, and it never runs.
- It is not a cast. `as` tells the compiler to stop arguing; `satisfies` asks it to check and then keeps quiet about the result.
Takeaway
Reach for `as const satisfies X` on configuration objects. You get the constraint enforced and the literal types kept, which used to be a choice.