#2 타입스크립트 동작 원리

KangMyungJoe·2021년 1월 2일
3

Typescript

목록 보기
2/2
post-thumbnail

타입스크립트 컴파일러(Typescript Compiler, TSC)

타입스크립트는 자바스크립트나 자바 같은 주요 언어와는 다른 방식으로 동작하므로, 컴파일러와 관련된 내용을 확실히 짚고 넘어야한다.

먼저, 프로그램은 프로그래머가 작성한 다수의 텍스트 파일로 구성된다.

어떤 방식으로 텍스트 파일이 실행되는걸까?

  1. 텍스트를 컴파일러 프로그램이 파싱하여 추상 문법 트리(abstract syntax tree, AST)라는 자료구조로 변환한다.

  2. 컴파일러 프로그램AST바이트코드로 변환한다.

  3. 런타임 프로그램에 바이트코드를 입력하여 평가받고 결과를 얻는다.

즉, 프로그램 실행이란, 컴파일러가 소스 코드를 파싱해 AST로 만들고, 다시 AST를 바이트코드로 변환한 것을 런타임이 평가하도록 지시하는 것

타입스크립트가 다른 언어와 다른 점은 컴파일러가 소스 코드를 바이트코드 대신 자바스크립트 코드로 변환한다는 점이다!

타입스크립트는 다른 언어보다 코드를 더 안전하게 만든다고 했는데 코드는 언제 안전해지나요?

타입스크립트는 컴파일 단계에서 AST를 만들어 결과 코드를 내놓기 전에 타입 확인 과정을 거친다. (타입 검사기를 사용한다)

typechecker: 코드의 타입 안전성을 검증하는 프로그램

타입스크립트의 마법은 타입 확인 과정에서 발생하며, 타입 확인 덕분에 프로그래머의 기대대로 프로그램이 실행될 수 있으며 실수를 방지할 수 있다.

전체적인 타입스크립트 컴파일 과정은 다음과 같다.

1~3은 TSC가 수행하며, 4~6은 브라우저, NodeJS, 기타 자바스크립트 엔진 등에서 수행한다.

보통 자바스크립트 컴파일러와 런타임은 엔진이라는 하나의 프로그램으로 합쳐진다.
프로그래머는 주로 이 엔진과 상호작용한다. V8(NodeJS, 크롬, 오페라에서 사용), 
스파이더몽키(파이어폭스), JSCore(사파리), 샤크라(엣지) 등이 이처럼 동작하며 
자바스크립트가 해석되는 (interpreted) 언어의 모습을 갖게 만든다.

과정 1~2에서는 소스 코드에 사용된 타입을 사용하지만, 과정 3에서는 이용하지 않는다.

즉, TSC타입스크립트 코드를 자바스크립트 코드로 컴파일할 때개발자가 사용한 타입을 확인하지 않는다.

개발자가 코드에 기입한 타입 정보는 최종적으로 만들어지는 프로그램에 아무런 영향을 주지 않으며, 단지 타입을 확인하는 데만 쓰인다.


타입 시스템 (type system)

타입 시스템이란, 타입 검사기가 프로그램에 타입을 할당하는 데 사용하는 규칙 집합이다.

타입 시스템에는 사용하는 보통 2가지 종류가 존재한다.

  1. 어떤 타입을 사용하는지를 컴파일러에 명시적으로 알려주는 타입 시스템
  2. 자동으로 타입을 추론하는 타입 시스템

2가지 시스템은 서로 장단점이 존재하고, 타입스크립트는 양측에 모두 영향을 받았다. 즉, 프로그래머가 타입을 명시할 지, 컴파일러가 추론하게 할 지를 정할 수 있다는 것이다.

const a: number = 10;  // 타입을 명시

const b = 10;		// 타입을 추론하게 함

타입스크립트 vs 자바스크립트

다음 표는 타입스크립트자바스크립트타입 시스템을 비교한 표다.

타입은 어떻게 결정될까?

동적 타입 바인딩이란, 자바스크립트가 프로그램을 실행해야만 특정 데이터의 타입을 알 수 있음을 의미한다. 반대로 타입스크립트는 점진적으로 타입을 확인한다.

타입스크립트는 컴파일 타임에 프로그램의 모든 타입을 알고 있을 떄 최상의 결과를 보여줄 수 있지만, 프로그램을 컴파일하는 데 반드시 모든 타입을 알아야 하는 것은 아니다.

이처럼 타입스크립트의 동작과 같은 점진적 타입 확인은 타입을 지정하지 않은 기존 자바스크립트 코드를 타입을 사용하는 타입스크립트로 마이그레이션할 때 매우 유용하다.

타입 변환

자바스크립트는 약한 타입 언어다. 예를 들어, 숫자와 배열을 더하는 유효하지 않은 연산을 수행하면 다양한 규칙을 적용해가며 개발자가 정말 의도한 바를 알아내려고 노력하고, 주어진 정보로 최상의 결과를 도출한다.

다음과 같은 예가 있다.

3 + [1]

1. 자바스크립트는 3이 숫자고 [1]이 배열임을 확인한다.
2. 개발자가 +를 사용했으므로 자바스크립트는 값을 연결하고 싶어하는 것으로 인지한다.
3. 자바스크립트는 3을 문자열 "3"으로 암묵적인 변환을 시도한다.
4. 자바스크립트는 [1]을 문자열 "1"로 암묵적인 변환을 시도한다.
5. 두 문자열을 붙여 "31"이라는 결과를 도출한다.

위와 같이 자바스크립트는 영리하게 타입을 변환하려 노력하는 반면 타입스크립트는 유효하지 않은 작업을 발견하는 즉시 불평한다.

동일한 예지만, 타입스크립트에서는 다르게 행동한다.

3 + [1]     // 에러 TS2365: '+' 연산자를 '3'과 'number[]' 타입에 적용 불가

'31'의 결과 값을 도출하고 싶은 경우

(3).toString() + [1].toString()  // '31'로 평가

올바르지 않은 연산을 수행하면 타입스크립트가 바로 그 부분을 지적하며, 의도를 명시해야 타입스크립트의 불평을 무사히 통과할 수 있다.

자바스크립트가 제공하는 이러한 종류의 암묵적 변환 때문에 원인을 추적하기 어렵고, 이는 골칫덩이다.

언제 타입을 검사할까?

자바스크립트는 주어진 상황에서 개발자가 무엇을 의도하는지에 맞춰 변환하려 노력할 뿐, 대부분의 상황에서 타입이 무엇인지 따지지 않는다.

하지만, 타입스크립트에서는 컴파일 타임에 코드의 타입을 확인하기 때문에 코드를 실행하지 않고도 에러를 즉시 확인할 수 있다.

에러는 언제 검출되는가?

자바스크립트는 런타임에 예외를 던지거나 암묵적 형변환을 수행한다. 즉, 프로그램을 실행해야만 어떤 문제가 있음을 확인할 수 있다. 운이 좋다면 단위 테스트를 실행하다가 발견할 수도 있겠지만, 그렇지 않을 경우 문제가 커진다.

타입스크립트는 컴파일 타임에 문법 에러와 타입 관련 에러를 모두 검출한다. 하지만, stack overflow network error Invalid Input타입스크립트가 컴파일 타임에 검출할 수 없는 런타임 에러도 많다.

profile
소통을 잘하는 개발자가 되고 싶습니다.

0개의 댓글