satisfies Operator (TS 4.9)
debt(d5/e1/b3/t7)
Closest to 'specialist tool catches it' (d5). The detection_hints list only 'typescript' with automated: no, meaning the TypeScript compiler itself will catch misuse (e.g. using 'as' when 'satisfies' is appropriate) only if you're actively reviewing type errors. It won't flag that you chose 'as' over 'satisfies' as a lint warning by default — a developer must understand the distinction and look for it, placing it between a default linter catch and pure code review.
Closest to 'one-line patch or single-call swap' (e1). The quick_fix explicitly states: replace 'as Type' with 'satisfies Type' for config objects. This is a single-keyword substitution at each call site — a straightforward one-line change per occurrence.
Closest to 'localised tax' (b3). The choice applies to web and cli contexts broadly, but satisfies is a per-expression operator. Its scope is localised to the specific type annotations where it's used. It doesn't impose a cross-cutting structural burden; only the files and components using the pattern are affected.
Closest to 'serious trap' (t7). The misconception field explicitly states that developers conflate satisfies with 'as' type assertion. This is a serious trap because 'as' and satisfies look syntactically similar in intent (both relate to types), but 'as' silences errors and widens types while 'satisfies' validates without widening. This directly contradicts how a developer familiar with 'as' would guess the operator behaves, and the 'obvious' migration path (using 'as' everywhere) is actually the wrong choice.
TL;DR
Explanation
Before satisfies, you had to choose: use 'as Type' (loses inference) or rely on inference (no type safety). satisfies validates the shape without widening. Example: const palette = { red: [255,0,0], green: '#00ff00' } satisfies Record<string, string | number[]> — TypeScript knows palette.red is number[] (not string | number[]) because inference is preserved. This enables calling .toUpperCase() on palette.green without a type assertion, while still checking it conforms to the Record type. Useful for config objects, CSS-in-JS, and any case where you want validation without losing specificity.
Common Misconception
Why It Matters
Common Mistakes
- Using 'as Type' when satisfies is more appropriate — 'as' silences errors.
- Using satisfies without understanding it preserves inferred types for each property.
- Expecting satisfies to change the runtime behaviour — it's compile-time only.
Code Examples
// As-assertion loses specificity:
const config = {
timeout: 5000,
endpoint: '/api'
} as Config; // config.timeout is now Config['timeout'], not 5000
type Config = { timeout: number; endpoint: string };
const config = {
timeout: 5000, // TypeScript knows this is 5000, not just number
endpoint: '/api' // TypeScript knows this is '/api', not just string
} satisfies Config;
config.timeout; // type: 5000 (literal) — not number