컴파일러
프로그램은 프로그래머가 작성한 다수의 텍스트 파일로 구성됩니다.
해당 텍스트를 컴파일러(compiler)라는 특별한 프로그램이 파싱 하여 추상 문법 트리(Abstract Syntax Tree, AST)라는 자료구조로 변환합니다.
AST는 공백, 주석, 그리고 탭 등의 결과를 완전히 무시하고, 다시 AST를 바이트코드(bytecode)라는 하위 수준의 표현으로 변환합니다.
바이트코드가 만들어졌으면 런타임(runtime)이라는 다른 프로그램에 바이트코드를 입력해 평가하고 결과를 얻을 수 있습니다.
즉, 프로그램을 실행하는 것은 컴파일러가 소스 코드를 파싱해 AST로 만들고, 다시 AST를 바이트코드로 변환한 것을 런타임이 평가하도록 지시한다는 의미입니다.
위의 과정을 요약하면, 아래와 같습니다.
- 프로그램이 AST로 파싱 됩니다.
- AST가 바이트코드로 컴파일됩니다.
- 런타임이 바이트코드를 평가합니다.
TypeScript가 다른 언어와 다른 점은 컴파일러가 코드를 바이트코드 대신 JavaScript 코드로 변환한다는 점입니다.
중요한 점은 TypeScript 컴파일러는 AST를 만들어 결과 코드를 내놓기 전에 타입 확인을 거친다는 것입니다.
타입 검사기(typechecker)
코드의 타입 안전성을 검증하는 특별한 프로그램
TypeScript의 마법은 타입 확인 과정에서 일어납니다.
타입 확인 덕분에 TypeScript는 프로그램이 개발자의 기대대로 실행될 수 있게 해 주고, 명백한 실수가 들어가지 않게 방지해 줍니다.
TS | 1. TypeScript 소스 → TypeScript AST 2. 타입 검사기가 AST를 확인 3. TypeScript AST → JavaScript 소스 |
JS | 4. JavaScript 소스 → JavaScript AST 5. AST → 바이트코드 6. 런타임에서 바이트코드를 평가 |
과정 1 ~ 3은 TSC가 수행하며, 과정 4 ~ 6은 브라우저, NodeJS, 기타 JavaScript 엔진 같은 JavaScript 런타임이 실행합니다.
과정 1 ~ 2에선 소스 코드에 사용된 타입을 이용하지만, 과정 3에선 이용하지 않습니다.
즉, TSC가 TypeScript 코드를 JavaScript 코드로 컴파일할 때는 개발자가 사용한 타입을 확인하지 않기 때문에 개발자가 코드를 기입한 타입 정보는 최종적으로 만들어지는 프로그램에 아무런 영향을 주지 않으며, 단지 타입 확인에만 쓰인다는 뜻입니다.
따라서 개발자 마음대로 프로그램의 타입을 바꾸고 개선하고 실험해도 기존의 프로그램이 망가질 염려가 없습니다:)