TypeScript's `satisfies` operator solves a problem most of us had learned to work around rather than realized was fixable: validating that a value matches a type without widening it or losing literal type inference in the process. Before `satisfies`, annotating a config object with an explicit type gave you the validation but widened literal string values to their general type, while skipping the annotation kept the literal types but gave up validation entirely; you couldn't have both at once.
Config objects and route definitions were the first places we reached for it, letting us keep literal string types for autocomplete while still getting a compile error if a required field is missing or mistyped. A routes configuration object, for instance, benefits from `satisfies` twice over: TypeScript checks that every route entry matches the expected shape, catching a missing `path` field or a `method` value that isn't one of the allowed HTTP verbs, while the literal path strings themselves stay narrowly typed rather than widening to `string`, which downstream code relies on for exhaustive route-matching logic.
A second pattern that's proven useful is validating theme or design-token objects, colors, spacing scales, defined as plain objects that need to satisfy a shape constraint (every color value is a valid hex string, for instance) while keeping each key's literal name available for autocomplete elsewhere in the codebase. `as const` alone gives you the literal types but no validation; a type annotation gives validation but loses the literals; `satisfies` combined with `as const` gives both together, which is the combination we now reach for by default on this kind of object.
The rollout across the team wasn't entirely friction-free. A few developers initially reached for `satisfies` in places where a simple type annotation would have done the same job with less unfamiliar syntax, since the operator is new enough that its specific value proposition, preserving literal inference, isn't obvious until you've hit the problem it solves firsthand. We ended up documenting two or three canonical examples internally rather than trying to explain the general rule in the abstract, since seeing the config-object case made the motivation click faster than any explanation of variance and type widening did on its own.
A third pattern that's held up well is validating discriminated union-like configuration objects, a set of named API client configurations, for instance, where each entry needs to satisfy a shared shape but individual entries have genuinely different literal values for a `type` or `provider` field that other parts of the code switch on. Using a plain type annotation here would have collapsed those literal fields to their general string type, breaking exhaustiveness checks in the switch statements that consume the configuration elsewhere; `satisfies` was the only option that gave us both validation at the definition site and precise literal types at every consumption site.
We haven't found much use for it beyond object literals so far, and that tracks with how the TypeScript team has talked about the feature; it's a narrow, well-scoped addition rather than a general-purpose tool, and we'd caution against reaching for it reflexively in places where a normal type annotation, an interface, or a generic function signature already solves the problem cleanly, since adding it where it isn't needed just adds unfamiliar syntax for the next developer reading the code without any corresponding benefit.