기본 패턴
ts
type Colors = "red" | "green" | "blue";
const palette = {
red: [255, 0, 0],
green: "#00ff00",
blue: [0, 0, 255],
} satisfies Record<Colors, string | readonly [number, number, number]>;설명
as const는 객체와 배열 리터럴을 더 구체적인 literal 타입으로 고정합니다. 문자열은 더 이상 넓은string으로 퍼지지 않고, 배열은 readonly tuple, 객체 속성은 readonly literal 쪽으로 좁아집니다.satisfies는 표현식이 어떤 타입 계약을 만족하는지 검사하면서도, 그 표현식의 구체적인 추론 결과는 최대한 유지하게 해 줍니다. 이 점이 단순 타입 annotation과 가장 큰 차이입니다.- 그래서
const palette: Record<Colors, ...>처럼 직접 어노테이션을 붙이면 각 속성의 구체성이 사라질 수 있지만,satisfies를 쓰면 키 검증과 정밀한 추론을 동시에 얻을 수 있습니다. - 실무에서는 설정 객체, 라우트 맵, 권한 테이블, 이벤트 핸들러 맵처럼 "키 집합은 검증하고 싶지만 값의 개별 정보는 유지하고 싶은" 구조에서 특히 강력합니다.
as const와satisfies는 함께 쓰일 때 TypeScript 코드의 품질을 크게 올려 줍니다. 하나는 추론 정밀도를 높이고, 다른 하나는 계약 검증을 담당하기 때문입니다.
빠른 정리
| 도구 | 역할 |
|---|---|
as const | 리터럴 값을 더 구체적이고 readonly하게 고정 |
satisfies | 타입 계약을 검증하되 표현식의 정밀한 추론 유지 |
| annotation과 차이 | 검사는 비슷하지만 추론 보존 정도가 다름 |
| 잘 맞는 경우 | 설정 객체, route map, 권한 테이블, 색상 팔레트 |
| 핵심 가치 | 검증과 추론 품질을 동시에 챙김 |
주의할 점
as const를 남용하면 지나치게 readonly하고 좁은 타입이 생길 수 있고, satisfies도 계약이 잘못 잡히면
기대한 검증을 못 합니다. 두 도구 모두 "무엇을 고정하고 무엇을 검증할지"가 먼저 분명해야 합니다.
참고 링크
3 sources