TypeScript 4.8 satisfies 연산자로 타입 안전성 개선하기
문제 상황
프로젝트에서 설정 객체를 다룰 때 타입 안전성과 자동완성을 동시에 확보하기 어려웠다. as const를 사용하면 자동완성은 되지만 타입 체크가 느슨했고, 명시적 타입 선언을 하면 리터럴 타입이 넓어져 자동완성이 제대로 동작하지 않았다.
type Colors = "red" | "green" | "blue";
// as const: 타입 체크 없음
const palette1 = {
primary: "red",
secondary: "yello" // 오타인데 에러 없음
} as const;
// 명시적 타입: 리터럴 타입 손실
const palette2: Record<string, Colors> = {
primary: "red",
secondary: "green"
};
// palette2.primary의 타입이 Colors로 넓어짐
satisfies 연산자
TypeScript 4.8에서 추가된 satisfies 연산자가 이 문제를 해결했다.
const palette = {
primary: "red",
secondary: "green",
accent: "blue"
} satisfies Record<string, Colors>;
// ✅ 리터럴 타입 유지
palette.primary; // 타입: "red"
// ✅ 타입 체크 동작
const wrong = {
primary: "yellow" // ❌ 에러 발생
} satisfies Record<string, Colors>;
실제 적용 사례
API 엔드포인트 설정에 적용했다.
type HttpMethod = "GET" | "POST" | "PUT" | "DELETE";
interface ApiEndpoint {
method: HttpMethod;
path: string;
}
const endpoints = {
getUser: { method: "GET", path: "/users/:id" },
createUser: { method: "POST", path: "/users" },
updateUser: { method: "PUT", path: "/users/:id" }
} satisfies Record<string, ApiEndpoint>;
// 자동완성과 타입 체크 모두 동작
endpoints.getUser.method; // 타입: "GET"
정리
satisfies는 타입 단언의 안전한 대안이다. 타입 체크와 타입 추론을 모두 챙길 수 있어서, 설정 객체나 상수 정의에 특히 유용했다. 팀 코드베이스에서 as const를 점진적으로 교체하는 중이다.