TypeScript 3.4 const assertion으로 타입 안전성 높이기

문제 상황

프로젝트에서 상수 객체를 정의할 때 타입 추론이 너무 넓게 되는 문제가 있었다.

const STATUS = {
  PENDING: 'pending',
  SUCCESS: 'success',
  ERROR: 'error'
};

// type은 { PENDING: string, SUCCESS: string, ERROR: string }

이렇게 되면 함수 파라미터로 특정 리터럴 타입을 기대할 때 정확한 타입 체크가 어려웠다.

const assertion 적용

TypeScript 3.4에서 추가된 as const를 사용하면 literal type으로 추론된다.

const STATUS = {
  PENDING: 'pending',
  SUCCESS: 'success',
  ERROR: 'error'
} as const;

// type은 { readonly PENDING: 'pending', ... }

type StatusType = typeof STATUS[keyof typeof STATUS];
// 'pending' | 'success' | 'error'

function updateStatus(status: StatusType) {
  // ...
}

객체뿐만 아니라 배열에도 유용했다.

const ROUTES = ['/', '/about', '/contact'] as const;
type Route = typeof ROUTES[number];
// '/' | '/about' | '/contact'

효과

  • enum 없이도 union type 생성 가능
  • readonly 속성으로 실수로 인한 변경 방지
  • 자동완성과 타입 체크 정확도 향상

기존 enum을 사용하던 부분을 점진적으로 const assertion으로 전환 중이다. 번들 크기도 줄고 코드도 더 간결해졌다.

TypeScript 3.4 const assertion으로 타입 안전성 높이기