TypeScript 4.8 satisfies 연산자로 타입 안전성 높이기

문제 상황

프로젝트에서 설정 객체를 관리하는 코드를 작성하던 중, 타입 단언(as)을 사용하면 타입 체크는 통과하지만 실제 런타임 에러가 발생하는 경우가 있었다.

type Colors = 'red' | 'green' | 'blue';

const palette = {
  primary: 'red',
  secondary: 'green',
  accent: 'bleu' // 오타
} as Record<string, Colors>; // 통과됨

palette.primary.toUpperCase(); // Property 'toUpperCase' does not exist

as로 단언하면 타입 체커가 실제 값을 검증하지 않고, 반환 타입도 넓어져서 메서드 자동완성이 동작하지 않았다.

satisfies 연산자

TypeScript 4.8에서 추가된 satisfies는 이 문제를 해결한다.

const palette = {
  primary: 'red',
  secondary: 'green',
  accent: 'bleu' // Error: Type '"bleu"' is not assignable
} satisfies Record<string, Colors>;

palette.primary.toUpperCase(); // 정상 동작

satisfies는 해당 타입을 만족하는지 검증만 하고, 변수의 타입은 실제 값으로부터 추론된다. 덕분에 문자열 메서드를 사용할 수 있고, 오타도 컴파일 단계에서 잡을 수 있다.

적용 사례

API 엔드포인트 설정에서 유용하게 사용했다.

type RouteConfig = {
  method: 'GET' | 'POST' | 'PUT' | 'DELETE';
  path: string;
};

const routes = {
  getUser: { method: 'GET', path: '/users/:id' },
  createUser: { method: 'POST', path: '/users' },
} satisfies Record<string, RouteConfig>;

// routes.getUser.method는 'GET'으로 좁혀진 타입

타입 안전성과 개발 경험을 모두 챙길 수 있어서 앞으로 자주 쓸 것 같다.