Book/Effective Typescript

Item 3. 코드 생성과 타입이 관계없음을 이해하기

Alraffe 2023. 2. 8. 01:15

타입스크립트 컴파일러는 두 가지의 역할을 수행한다.

  1. 구버전의 자바스크립트로 트랜스파일
  2. 타입 오류 체크 

이 둘은 독립적으로 이루어지기 때문에 타입오류가 있는 코드도 컴파일이 가능하다. 만약 오류가 있을 경우 컴파일 하지 않으려면  noEmitOnError를 설정하거나 빌드 도구에 적용하면 된다.

 

런타임에는 타입체크가 불가능하다. 따라서 instanceof와 같이 런타임에 체크가 일어나는 경우 타입체크를 정상적으로 할 수 없다.

이러한 문제를 해결할 수 있는 방법은

 

  1. 런타임에도 타입 정보를 체크할 수 있도록 코드 작성

function caculateArea(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 caculateArea(Shape){
	if(shape.kind === 'rectangle'){
    shape; //타입이 Rectangle
    return shape.width * shape.height;
    }else{
    shape; // 타입이 Square
    return shape.width * shape.width;
    }
}

 

 

  3. 타입을 클래스로 선언하기

 클래스로 만들면 타입과 값을 둘 다 사용할 수 있다. 즉, 런타임에 접근 불가한 타입과 런타임에도 접근 가능한 값을 사용해 오류를 없애는 것이다.

 

class Square {
  constructor(public width: number) {}
}
class Rectangle extends Square {
  constructor(public width: number, public height: number) {
    super(width);
  }
}
type Shape = Square | Rectangle;

function calculateArea(shape: Shape) {
  if (shape instanceof Rectangle) {
    shape;  // Type is Rectangle
    return shape.width * shape.height;
  } else {
    shape;  // Type is Square
    return shape.width * shape.width;  // OK
  }
}

 

 

타입 연산은 런타임에 영향을 주지 않는다.

컴파일된 아래 코드를 보면 as number 부분인 타입을 연산하는 부분은 제거된다.

function asNumber(val: number | string): number {
  return val as number;
}

 

타입은 런타임 성능에 영향을 주지 않는다.

이것은 자바스크립트 파일로 변환하는 시점에 타입, 타입 연산자는 제거되기 때문! 하지만 빌드과정에서는 오버헤드가 있다.

 

더보기

제목 : 이펙티브 타입스크립트 : 동작 원리의 이해와 구체적인 조언 62가지

출판사 : 오랠리

지은이 : 댄 밴더캄

발행 : 2쇄 21년 11월 4일