Chapter 9

코드 작성 및 실행

  • 9.1 ECMAScript 기능을 타입스크립트 고유 기능보다 우선하기
  • 9.2 소스맵을 사용하여 타입스크립트 디버깅하기
  • 9.3 런타임 타입을 위해 값 공간에서 타입 재구성하기
  • 9.4 DOM 계층 구조 이해하기
  • 9.5 실행 환경에 맞는 타입 모델 사용하기
  • 9.6 타입 체크에 단위 테스트를 도입하기
  • 9.7 컴파일러 성능에 주의하기

TS를 잘 쓴다는 건 타입만 잘 쓰는 게 아니야. 실제로 코드를 작성하고 실행하고 디버깅하는 과정에서 알아야 할 것들이 있거든.

TS 초기에는 enum, namespace, parameter properties 같은 JS에 없는 고유 기능을 많이 추가했는데, 지금은 방향이 바뀌었어. 런타임 동작은 ECMAScript 표준 기능을 쓰고, TS는 타입 체크 용도로만 쓰라는 게 원칙이야. enum 대신 유니온 타입이나 as const를 쓰고, namespace 대신 ES 모듈을 쓰고, 실험적 데코레이터 대신 TC39 표준 데코레이터를 써야 해. TS를 타입 체커로만 쓰면 esbuild, swc 같은 다른 빌드 도구와의 호환성도 좋아져.

TS 코드를 디버깅할 때는 **소스맵(source map)**이 필수야. tsconfig.json에서 sourceMap: true로 활성화하면 브라우저 DevTools에서 원본 TS 코드를 볼 수 있고, 브레이크포인트도 걸 수 있어. 다만 프로덕션에 소스맵을 배포하면 소스 코드가 노출될 수 있으니까 주의해야 해.

1장에서 "타입은 런타임에 사라진다"고 했는데, 런타임에 타입 정보가 필요한 경우가 실제로 있잖아. API 응답 검증, 폼 유효성 검사 같은 거. 해결법은 타입 정보를 값으로도 표현하는 거야. 태그드 유니온의 kind 속성은 런타임에도 존재하니까 분기에 쓸 수 있고, 클래스는 instanceof로 런타임 체크가 가능하지. 2판에서는 Zod 같은 스키마 검증 라이브러리를 적극 권장하는데, 하나의 스키마 정의에서 런타임 검증과 타입 추론을 동시에 할 수 있어서 진짜 편해.

DOM을 다룰 때는 타입 계층(EventTarget -> Node -> Element -> HTMLElement -> HTMLInputElement)을 알아야 하고, document.getElementByIdHTMLElement | null을 반환한다는 것, e.currentTargete.target보다 타입 안전한 경우가 많다는 것도 알아둬야 해.

TS 코드가 실행되는 환경에 따라 사용 가능한 API가 다르니까, tsconfig.jsonlib 옵션으로 제어해야 해. Node.js 환경이면 DOM을 빼고, 브라우저 환경이면 @types/node를 빼야 이상한 충돌이 안 생겨.

타입이 잘 동작하는지도 테스트해야 하고, @ts-expect-error를 활용하면 "이 코드는 타입 에러가 나야 정상"을 검증할 수 있어. 프로젝트가 커지면 TS 컴파일 시간이 느려질 수 있는데, tsc --generateTrace로 원인을 찾고, --incremental 빌드와 project references로 대응할 수 있어. skipLibCheck를 켜면 빌드 속도가 빨라지지만 타입 선언 오류를 못 잡는 트레이드오프가 있지.


정리

9장 읽고 기억할 거 세 가지:

  1. TS 고유 런타임 기능(enum, namespace) 대신 ECMAScript 표준을 쓰라. TS는 타입 체커로만 활용하는 게 장기적으로 이득.
  2. 런타임에 타입이 필요하면 태그드 유니온, 클래스, 또는 Zod 같은 스키마 라이브러리를 쓰라. 타입과 런타임 검증을 한 곳에서 관리.
  3. 컴파일 성능이 느려지면 진단 도구로 원인을 찾고, incremental 빌드와 project references를 활용하라.