JavaScript 개발자가 결국 TypeScript를 써야 하는 이유

JavaScript의 유연함 뒤에 숨은 불안정성을 해결하기 위해 TypeScript가 작동하는 원리와 두 언어의 기술적 관계를 정리합니다.

2026년 3월 13일


프로젝트 규모가 커질수록 가장 골치 아픈 건 **'런타임 에러'**다. 정의되지 않은 값을 참조하거나 타입이 달라 발생하는 오류는 실행 전까지 파악하기 어렵다. JavaScript는 유연하지만 개발자가 부담해야 할 불확실성이 크다. 이 문제를 해결하기 위해 도입하는 TypeScript의 내부 작동 원리와 JavaScript와의 관계를 정리한다.


1. 상위 집합(Superset) 관계

TypeScript는 JavaScript의 모든 기능을 포함하며, 그 위에 정적 타입(Static Typing) 시스템을 추가한 언어다.

  • 호환성: 모든 JavaScript 코드는 유효한 TypeScript 코드다. 확장자를 .js에서 .ts로 변경하는 것만으로 도입이 가능하다.
  • 컴파일: 브라우저와 Node.js는 TypeScript를 직접 해석하지 못한다. tsc 컴파일러를 통해 타입 정보를 제거한 순수 JavaScript로 변환해야 실행할 수 있다.

2. 정적 타입 체크의 원리

에디터에서 실시간으로 에러를 감지하는 것은 TypeScript Language Service의 역할이다.

  1. LSP(Language Server Protocol): 에디터와 언어 서비스가 통신하며 코드를 분석한다.
  2. 구조화(AST): 코드를 **추상 구문 트리(AST)**로 변환하여 논리적 구조를 파악한다.
  3. 심볼 바인딩: 변수나 함수의 선언과 사용 위치를 연결하여 식별자를 관리한다.
  4. 타입 검사: 분석된 구조를 바탕으로 할당된 값이 선언된 타입과 일치하는지 대조한다.

3. tsc: 셀프 호스팅 컴파일러

TypeScript 컴파일러인 tscTypeScript로 작성되었다.

이를 **셀프 호스팅(Self-hosting)**이라 한다. 자신들이 만든 언어로 컴파일러라는 대규모 프로그램을 직접 구축하여 언어의 성능과 기능을 증명한 사례다. 우리가 사용하는 패키지는 이 컴파일러가 JavaScript로 변환된 결과물이다.


4. 빌드 환경과 자동화

현대적인 개발 도구는 컴파일 과정을 자동화하여 개발 생산성을 유지한다.

  • Watch Mode: 빌드 도구가 파일 저장을 감지하여 즉시 컴파일을 수행한다.
  • HMR(Hot Module Replacement): 수정된 모듈만 실시간으로 교체하여 브라우저 새로고침 없이 변경 사항을 반영한다.
  • 타입 삭제(Type Erasure): 컴파일 과정에서 모든 타입 선언이 제거된다. 최종 .js 파일에는 런타임 로직만 남으므로 성능 오버헤드가 없다.

5. JavaScript 자체에 타입을 넣지 못하는 이유

  • 브라우저 호환성: 브라우저는 JavaScript 표준(ECMAScript)만 해석한다. 타입 구문이 포함된 코드를 그대로 실행하면 문법 에러(Syntax Error)가 발생한다.
  • 표준 합의: TC39 위원회에서 타입 구문을 표준에 포함하려는 논의가 진행 중이나, 전 세계 브라우저가 이를 지원하기까지는 상당한 시간이 소요된다.

마무리

  • 안전성: 실행 전 단계에서 논리적 오류를 사전에 차단한다.
  • 생산성: 명시적인 타입을 바탕으로 강력한 자동 완성 기능을 제공한다.
  • 성능: 런타임에는 순수 JavaScript만 남으므로 성능 손실이 없다.

TypeScript는 단순한 도구를 넘어 JavaScript 프로젝트의 유지보수성을 확보하기 위한 표준적인 인프라로 자리 잡았다.