[TS] 컴파일과 타입의 독립성
작성:    
업데이트:
카테고리: Effective TS
태그: Effective TS, FE Language, TS
본 포스트는 이펙티브 타입스크립트를 보며 정리한 내용입니다.
“타입스크립트의 타입과 구문들은 컴파일 시간에만 존재하고, 런타임에는 존재하지 않는다. 자바스크립트 코드로 컴파일을 하는 것과 타입을 체크하는 것은 완전히 독립적이다.”
런타임에 타입 정보를 유지하는 방법
- 타입스크립트는 타입 정보를 컴파일 시간에만 유지한다.
- 즉, 런타임에는 타입 체크가 불가능하다.
interface Square {
width: number;
}
interface Rectangle extends Square {
height: number;
}
type Shape = Square | Rectangle;
function calculateArea(shape: Shape) {
if (shape instanceof Rectangle) {
// ~~~~~~~~~ 'Rectangle'는 형식만 참조하지만,
// 여기서는 값으로 사용되고 있습니다.
return shape.width * shape.height;
// ~~~~~~ 'Shape' 형식에 'height' 속성이 없습니다.
} else {
return shape.width * shape.width;
}
}
이 문제를 해결하는 방법들을 살펴보자.
1. 속성 체크
in
연산자를 사용하여 속성의 존재 여부 확인
interface Square {
width: number;
}
interface Rectangle extends Square {
height: number;
}
type Shape = Square | Rectangle;
function calculateArea(shape: Shape) {
if ('height' in shape) {
shape; // 타입이 Rectangle
return shape.width * shape.height;
} else {
shape; // 타입이 Square
return shape.width * shape.width;
}
}
2. 태그 기법
런타임에 접근할 수 있는 타입 정보를 명시적으로 저장
interface Square {
kind: 'square';
width: number;
}
interface Rectangle {
kind: 'rectangle';
height: number;
width: number;
}
type Shape = Square | Rectangle;
function calculateArea(shape: Shape) {
if (shape.kind === 'rectangle') {
shape; // 타입이 Rectangle
return shape.width * shape.height;
} else {
shape; // 타입이 Square
return shape.width * shape.width;
}
}
타입과 성능
- 타입과 타입 연산자는 JS 변환 시점에 제거
- 즉, 런타임 성능에 아무런 영향을 주지 않는다.
컴파일러 오버헤드
- 타입스크립트 컴파일러는
런타임 오버헤드
는 없지만빌드타임 오버헤드
는 있다. - 오버헤드가 커지면, 빌드 도구에서
트랜스파일만(transpile only)
을 설정해 타입 체크를 건너뛸 수 있다.
호환성과 성능의 trade-off
- 타입스크립트가 컴파일하는 코드는 선택해야 한다.
- 오래된 런타임 환경을 지원: 성능을 버리고 호환성을 취한다.
- 성능 중심의 네이티브 구현제를 선택: 호환성을 버리고 성능을 취한다.
- 예를 들면 제너레이터 함수가 ES5 타겟으로 컴파일되려면, 호환성을 위한 특정 헬퍼 코드를 추가해야 한다. 이 경우 제너레이터 호환성을 위한 성능 오버헤드 또는 성능을 위한 네이티브 구현체 사이에서 선택해야 한다.
References
- 속성 체크 [15p]
- 태그 기법 [16p]
- 타입과 성능 [20p]
댓글남기기