코드 생성과 타입 관계 - 이펙티브 타입스크립트

최봉수·2022년 8월 11일
0

타입 오류가 있는 코드도 컴파일이 가능하다

  • 컴파일은 타입 체크와 독립적으로 동작하기 때문에, 타입 오류가 있는 코드도 컴파일이 가능하다

코드에 오류가 있을 때 "컴파일에 문제가 있다"고 말하는 것은 잘못 되었다. 왜냐하면 오직 코드 생성만이 '컴파일'이라고 할 수 있고, 작성한 ts가 유효한 js라면 ts 컴파일러는 컴파일을 한다. 그러므로 코드에 오류가 있을 때는 "타입 체크에 문제가 있다"고 말하는 것이 더 정확한 표현


런타임에는 타입 체크가 불가능하다

  • ts의 타입은 제거 가능하기 때문에 js로 컴파일되는 과정에서 모든 인터페이스, 타입, 타입 구문은 제거된다.
  • 런타임에서 타입 정보를 유지하려면 '태그 기법 혹은 태그된 유니온(tagged union)'이나, 타입(런타임 접근x)과 값(런타임 접근o)을 둘 다 사용하기 위해선 타입을 Class로 만들면 된다.

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

  • 예를 들어 as number는 타입 연산이고 런타임 동작에는 아무 영향을 주지 않는다.
  • 값을 정제하기 위해선 런타임 값을 체크해야 하고, 이는 js 연산을 통해 변환해야 한다.

런타임 타입은 선언된 타입과 다를 수 있다

  • ts의 타입은 런타임에 제거되기 때문에 선언한 ts 타입과 런타임의 타입은 다를 수 있다.
    - 예를 들어 API 반환 값이 boolean이라고 선언했지만, API를 잘못 파악해서 실제로는 string이 반환 된다던지
    - 또는 배포 후에 API가 변경되어 원래는 선언한 타입으로 잘 반환하던 값이 다른 타입으로 변경 된다던지 등
  • 선언된 타입이 언제든지 달라질 수 있다는 것을 명심해야한다.

TS 타입으로는 함수를 오버로드 할 수 없다

  • ts는 타입과 런타임 동작이 무관하기 때문에, 함수 오버로드는 불가능하다.
  • ts가 함수 오버로딩을 지원하긴 하지만, 그건 온전히 타입 수준에서만 동작한다.
  • 하나의 함수에 여러 개의 선언문을 작성할 수 있지만, 구현체는 오직 하나뿐.
// 선언문
function add(a: number, b: number): number;
function add(a: string, b: string): string;

// 구현체
function add(a, b) {
	return a + b;
};

const numberAdd = add(1, 2); // 3 (number)
const stringAdd = add("1", "2"); // "12" (string)

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

  • 타입과 타입 연산자는 js로 컴파일되는 시점에서 제거되기 때문에, 런타임 성능에 아무런 영향을 주지 않는다.
  • ts의 정적 타입은 실제로 아무런 비용이 들지않는다.

요약

  • 코드 생성은 타입 시스템과 무관하며, ts의 타입은 런타임 동작이나 성능에 아무런 영향을 주지 않는다.
  • 타입 오류가 존재하더라도 코드 생성(컴파일)은 가능하다.
  • ts의 타입은 런타임에 사용할 수 없다.
  • 런타임에 타입을 지정하려면, 타입 정보 유지를 위한 별도의 방법이 필요하다.
    - 일반적으로는 태그된 유니온(tagged union)과 속성 체크 방법을 사용한다.
    - ts의 타입과 런타임의 값, 둘 다 제공해야 한다면, Class를 이용해 작성한다
profile
돈이 좋아

0개의 댓글