"매 satisfies는 type 을 검증하면서 narrow type 을 보존". TS 4.9 (2022) 도입. as 와 달리 type assertion 이 아니라 type validation — value 의 inferred (narrow) type 은 그대로 유지하면서 declared shape 만 강제. 2026 기준 config object, route map, palette 같은 record 패턴 의 standard.
매 핵심
매 vs Type Annotation
const x: T = value → x 의 type 은 T (widening)
const x = value satisfies T → x 의 type 은 inferred narrow type, 단 T 호환 강제
매 vs as
as 는 unsafe cast (런타임 보장 X)
satisfies 는 compile-time validation (값 자체의 narrow type 을 잃지 않음)
Discriminated union literal — kind 가 narrow string literal 로 유지.
💻 패턴
Palette: widening 방지
typeColor="red"|"green"|"blue"|`#${string}`;constpalette={primary:"red",secondary:"#00ff00",accent:"blue",}satisfiesRecord<string,Color>;// palette.primary: "red" (narrow), not Color
constr:"red"=palette.primary;// OK
typeEvent=|{kind:"click";x: number;y: number}|{kind:"key";code: string};constevents=[{kind:"click",x: 10,y: 20},{kind:"key",code:"Enter"},]satisfiesEvent[];// events[0].x is number; kind narrow to "click"
Generic helper preserving inference
functiondefineConfig<TextendsRecord<string,unknown>>(c: T):T{returnc;}// Old way — full T preserved but no shape check.
// satisfies way:
constcfg={port: 3000,host:"localhost",}satisfies{port: number;host: string};// cfg.port: number (not number literal). add `as const` for literal.
언제: Config / palette / route map 작성 시 narrow literal 보존이 필요할 때. 매 schema validation + autocomplete 동시 요구.
언제 X: Function parameter type (annotation 만으로 충분). 매 simple variable typing.
❌ 안티패턴
as Record<...> cast: 매 unsafe. 매 satisfies 가 safer alternative.