TypeScript 3.4 const assertion과 readonly 배열 활용
배경
회사 프로젝트를 TypeScript 3.4로 업그레이드하면서 const assertion 기능을 살펴보게 되었다. 기존에는 상수 객체나 배열을 정의할 때 타입이 넓게 추론되어 별도 타입 정의가 필요했는데, 이 부분을 개선할 수 있었다.
기존 문제
설정 객체를 다룰 때 타입 추론이 불완전했다.
const config = {
apiUrl: 'https://api.example.com',
timeout: 5000
};
// config.apiUrl은 string으로 추론됨 (리터럴 타입 아님)
배열의 경우도 마찬가지였다.
const routes = ['home', 'about', 'contact'];
// string[]로 추론되어 구체적인 값 검증 불가
const assertion 적용
as const를 사용하면 리터럴 타입으로 좁혀진다.
const config = {
apiUrl: 'https://api.example.com',
timeout: 5000
} as const;
// config.apiUrl은 'https://api.example.com' 타입
const routes = ['home', 'about', 'contact'] as const;
type Route = typeof routes[number]; // 'home' | 'about' | 'contact'
실제 적용 사례
API 엔드포인트 관리 코드를 리팩토링했다.
const ENDPOINTS = {
users: '/api/users',
posts: '/api/posts',
comments: '/api/comments'
} as const;
type Endpoint = typeof ENDPOINTS[keyof typeof ENDPOINTS];
function fetchData(endpoint: Endpoint) {
// 타입 안전성이 보장된 API 호출
return fetch(endpoint);
}
fetchData(ENDPOINTS.users); // OK
fetchData('/api/wrong'); // 타입 에러
결과
- 별도 타입 선언 없이 타입 안전성 확보
- 설정 객체의 불변성 보장 (readonly)
- Union 타입 자동 생성으로 코드 중복 감소
프로젝트 전반의 상수 관리 패턴을 개선할 수 있었다.