TypeScript 5.0 satisfies 연산자로 타입 안전성 높이기
문제 상황
프로젝트에서 API 엔드포인트를 상수로 관리하는데, as const를 사용하면 타입이 너무 좁아지고, 그냥 선언하면 타입 체크가 느슨해지는 문제가 있었다.
const routes = {
users: '/api/users',
posts: '/api/posts',
invalid: '/api/wrong' // 오타가 있어도 감지 못함
} as const;
type Route = typeof routes[keyof typeof routes];
satisfies 연산자 도입
TypeScript 5.0의 satisfies를 사용하니 타입 제약을 검증하면서도 원본 타입을 유지할 수 있었다.
type ApiRoute = `/api/${string}`;
const routes = {
users: '/api/users',
posts: '/api/posts',
comments: '/api/comments'
} satisfies Record<string, ApiRoute>;
// 타입 추론 유지되어 자동완성 동작
const userRoute = routes.users; // string 타입
실무 적용 케이스
특히 설정 객체나 테마 정의에서 유용했다.
type ColorScheme = {
primary: string;
secondary: string;
background: string;
};
const theme = {
primary: '#3b82f6',
secondary: '#8b5cf6',
background: '#ffffff',
// accent: '#000' // 누락 시 에러 발생
} satisfies ColorScheme;
// theme.primary는 string으로 추론됨
as const와 달리 리터럴 타입으로 좁혀지지 않아서, 동적으로 값을 할당해야 하는 경우에 더 유연했다.
결론
타입 안전성과 추론의 균형을 맞추는 데 satisfies가 적절했다. 기존 코드베이스의 설정 객체들을 점진적으로 마이그레이션하고 있다.