노트

satisfies 연산자

The satisfies Operator

프론트엔드#ts · 연결된 개념 5개

쉽게 말하면

satisfies는 공항에서 가방이 기내 규격에 맞는지 재 보기만 하고 가방 속 물건은 그대로 두는 검사예요. 규칙은 지키게 하면서, 쓸 때는 값의 정확한 타입을 그대로 쓸 수 있죠.

비유의 한계 ': 타입' 표기는 짐을 규격 상자에 옮겨 담는 것과 같아서 구체적인 타입이 넓어져요. as 단언은 전혀 다른 짐만 막고 나머지는 말만 믿어 주지만, satisfies는 실제로 재 보고 안 맞으면 에러를 내요.

satisfies(TypeScript 4.9+)는 값이 어떤 타입을 만족하는지 검사하되, 값에서 추론된 구체적인 타입은 그대로 유지하는 연산자다.

방식타입 검사구체적 추론 유지
const x: T = …✅❌ (T로 넓어짐)
표기 없음❌✅
const x = … satisfies T✅✅
type Colors = Record<string, string | [number, number, number]>
 
const a: Colors = { red: [255, 0, 0] }
a.red.map(v => v * 2)            // ❌ string | 튜플로 넓어져 map을 모름
 
const b = { red: [255, 0, 0], green: '#0f0' } satisfies Colors
b.red.map(v => v * 2)            // ✅ 튜플로 남아 있음
  • 설정 객체·라우트 표처럼 "키와 값 모양은 규칙대로 강제하고, 쓸 때는 정확한 타입이 필요한" 곳에 맞는다
  • as const satisfies T로 리터럴 타입까지 고정하면서 모양을 검사할 수 있다
  • as T(타입 단언, Type Assertion)는 검사를 우회해 거짓말을 허용하지만, satisfies는 틀리면 에러를 낸다
  • 다만 as도 아무 타입으로나 바꿔 주지는 않는다. 원래 타입보다 더 구체적이거나 덜 구체적인 타입으로만 단언할 수 있어서 "hello" as number는 에러다. expr as unknown as T처럼 unknown(또는 any)을 거쳐 두 번 단언하면 이 최소한의 검사까지 끈다. 단언은 컴파일 때 지워지므로 틀려도 런타임 오류가 나지 않는다

배경은 타입 추론과 타입 검사, 상수 객체를 유니언으로 바꾸는 패턴은 매핑된 타입과 keyof·enum과 as const 객체 참고.

출처: TypeScript 4.9 - The satisfies Operator · TypeScript Handbook - Type Assertions

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • 기본형 집착

    전화번호·금액·우선순위 같은 도메인 개념을 끝까지 문자열이나 숫자로만 다루는 냄새. 같은 검증과 포맷 코드가 여기저기 반복되고, 문자열로 모든 걸 표현하는 "stringly typed" 코드가 된다.

  • 타입 좁히기와 타입 가드

    타입 좁히기(Narrowing)는 선언된 넓은 타입(유니언, unknown)을 실행 경로를 따라 더 구체적인 타입으로 줄여 가는 과정이다. 그 근거가 되는 런타임 검사를 타입 가드(Type Guard)라고 한다.

  • 제네릭

    제네릭(Generics)은 타입을 매개변수처럼 받아, 여러 타입에 같은 로직을 재사용하면서도 타입 정보를 잃지 않게 하는 기능이다.

  • 유니언·인터섹션·리터럴 타입

    유니언 타입(Union Type, A | B)은 "A이거나 B인 값"이고, 인터섹션 타입(Intersection Type, A & B)은 "A이면서 B인 값"이다. 리터럴 타입(Literal Type)은 'left'나 3처럼 특정 값 하나만 허용하는 타입이다.

  • 인덱스 시그니처

    인덱스 시그니처(Index Signature)는 속성 이름을 미리 다 알 수는 없지만 값의 모양은 알 때, [key: string]: T처럼 "어떤 키로 꺼내든 값은 T"라고 적는 TypeScript 문법이다. 키를 모르는 사전(dictionary) 모양의 객체를 표현할 때 쓴다.

보기 옵션