TypeScript Compiler
- Read TSConfig
- Pre-process Files
- import 구문들을 따라가서 모든 가능한 파일을 읽음
- Tokenize and Parse
- Binder
- syntax tree에서 식별자들을 symbol로 바꿈
- Type Check
- binder와 syntax tree를 사용하여 코드 내에 오류를 찾음
- Transform
- syntax tree를 tsconfig options에 맞게 바꿈
- Emit
- syntax tree를 .js, .d.ts, 그리고 다른 파일들로 출력함
Convert code to syntax tree
scanner
- space, ending quote로 분리된 text를 syntax token로 변환함
parser
- 위 예시의 AST 요소들
- VariableDeclaration :
const msg: string = 'hello';
- Identifier : 'msg'
- StringKeyword : 'string'
- StringLiteral : 'hello'
- 위 예시의 AST 요소들
- VariableDeclaration :
const num: number = 123;
- Identifier : 'num'
- NumberKeyword : 'number'
- NumberLiteral : 123
Type Checking
binder
- 정의된 identifier가 있는 symbol tables을 만듬
- 모든 syntax tree node에 parent를 설정함
- parent-child관계로 연결된 노드를 parent 방향으로 탐색할 수 있음
- TS Playground의 plugin을 사용하여 symbol table을 확인할 수 있음
- 위 예제에서는 symbol table에 'welcome'과 'msg' symbol이 추가됨
- flow nodes를 만듬
- 코드로부터 flow graph를 만듬
- if condition is true, if condition is false와 같은 조건문에 의해 flow conditionals가 만들어짐
- type checking할 때, flow graph를 사용해서 코드가 어떻게 영향을 받는지 확인함
- 전체 문맥을 이해하고 분석함
- Strict vs Module
- 중복된 identifier을 확인함
type checker
- type checker는 syntax tree를 순회하면서 각 부분에 대해서 확인함
- type이 맞는지 확인함
- type이 명시되어 있지 않은 경우, 값으로부터 type을 추론하여 초기화함
- type inference
- generic type
- contexual typing
- syntax tree를 거슬러 올라가면서, type에 대응되는 내용을 찾음
type Adder = {
inc(n: number): number
}
const add: Adder = {
inc(n) { return n + 1}
}
Creating JavaScript Files
emitter
- syntax tree을 files(.js, .map, d.ts)로 바꿈
- TypeScript syntax tree를 JavaScript Tree로 바꿈
- TypeScript 문법을 삭제함
- JavaScript ES 버전에 따라 변환함
- d.ts file을 만듬
- d.ts file : 식별자들의 type에 대한 내용이 담긴 파일
참고