핵심 요약
함수 타입 파라미터에 const 수식어를 붙이면 인자가 자동으로 가장 좁은 리터럴 타입으로 추론된다. as const를 호출 지점마다 쓰던 번거로움이 사라진다.
기본 문법
// ❌ 기존: widening으로 string[]
function pick<T>(items: T[]): T { /* ... */ return items[0]; }
const r1 = pick(['a', 'b', 'c']); // string
// ✅ const 타입 파라미터
function pick<const T>(items: readonly T[]): T { /* ... */ return items[0]; }
const r2 = pick(['a', 'b', 'c']); // 'a' | 'b' | 'c'
실전 유스케이스
1) 라우터 타입 안전성
function defineRoute<const P extends string>(path: P) {
return { path };
}
const r = defineRoute('/users/:id'); // path: "/users/:id"
2) 상태 머신
function machine<const S extends Record<string, unknown>>(def: S): S {
return def;
}
const m = machine({
initial: 'idle',
states: ['idle', 'loading', 'done'],
});
// m.states → readonly ['idle','loading','done']
3) 이벤트 명 목록
function createEmitter<const E extends readonly string[]>(events: E) {
type Name = E[number];
return { on(e: Name, cb: () => void) { /* ... */ } };
}
const ee = createEmitter(['login', 'logout']);
ee.on('login', () => {}); // ✅
ee.on('open', () => {}); // ❌ 타입 에러
주의사항
- readonly 전파: const T로 추론된 배열/객체는 readonly. 가변 배열 API에 넘길 땐 복사 필요.
- 함수 오버로드와 결합 시 추론 우선순위 확인.
- 런타임 동작 변화 없음: 순수 컴파일 타임 기능.
as const와 언제 쓸까
- 함수 시그니처 단에서 보장하고 싶다 →
const T - 호출자가 명시적으로 리터럴을 고정하고 싶다 →
as const - 둘 다 써도 무방. 중복 시
const T가 우선.
자주 묻는 질문
5.8 이전 버전에서는?
호출자에게 as const를 요구하거나, 타입을 명시적으로 전달해야 한다. DX 개선이 크다.
type alias에도 쓸 수 있나?
함수·메서드의 타입 파라미터에만 사용 가능. 타입 별칭의 제네릭 파라미터에는 지원되지 않는다.
댓글 0