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

Summary

  • 코드 생성은 타입 시스템과 무관하다. 빌드 타임을 희생하는 것일 뿐, 타입스크립트 파일(.TS)에서 자바스크립트로 트랜스파일 되는 과정에서 결과물(.JS)로부터 타입과 타입 연산자가 지워진다. 따라서 타입스크립트의 타입은 자바스크립트 런타임 동작이나 성능에 영향을 주지 않는다.

  • 타입 오류가 존재해도 옵션을 허용함에 따라 코드 생성(컴파일)은 가능하다.

  • 타입스크립트 타입은 런타임에는 사용할 수 없으므로, 런타임에 타입을 지정하려면 별도의 방법이 필요하다.

    • 일반적으로는 태그된 유니온과 속성 체크 방법을 사용한다.

      interface Square {
        kind: 'square'
        width: number
      }
      
      interface Rectangle {
        kind: 'rectangle'
        height: number
        width: number
      }
      
      type Shape = Square | Rectangle
      
      // 속성을 체크하는 방법
      function calculateArea1(shape: Shape) {
        if ('height' in shape) {
          shape; // 타입이 Rectangle
          console.log(shape.height) // 오류 안남
          return shape.width * shape.height
        } else {
          shape; // 타입이 Square
          console.log(shape.height) // 오류
          return shape.width * shape.width
        }
      }
      
      // 런타임에 접근 가능한 타입 정보를 명시적으로 제공하는 ‘태그’ 기법
      function calculateArea2(shape: Shape) {
        **if (shape.kind === 'rectangle') {**
          shape; // 타입이 Rectangle
          return shape.width * shape.height
        } else {
          shape; // 타입이 Square
          return shape.width * shape.width
        }
      }
    • 또는 클래스같이 타입스크립트 타입과 런타임 값 둘 다 제공하는 방법이 있다.

      class Square {
        constructor(public width: number) {}
      }
      
      class Square {
        public width: number
      
        constructor(width: number) { this.width = width }
      }
      
      class Rectangle {
        constructor(public width: number, public height: number) {
          super(width)
        }
      }
      type Shape = Square | Rectangle // type == interface
      
      // 클래스를 이용하면 instanceof를 활용하여 타입을 구분할 수 있다.
      function calculateArea1(shape: Shape) {
        // Rectangle은 클래스이므로 타입이기도 하고 값이기도 하여 instanceof를 사용할 수 있다.
        if (shape instanceof Rectangle) {
          shape; // 타입이 Rectangle
          return shape.width * shape.height
        } else {
          shape; // 타입이 Square
          return shape.width * shape.width
        }
      }

Last updated