Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
TypeScript_コンパイラの内側に片足を入れる
Search
ryounasso
November 23, 2023
Programming
990
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
TypeScript_コンパイラの内側に片足を入れる
kansai.ts #4 で発表した資料
https://kansaits.connpass.com/event/299545/
ryounasso
November 23, 2023
More Decks by ryounasso
See All by ryounasso
明日から始めるリファクタリング
ryounasso
0
250
駆け足で Google から学ぶテスト設計の指針
ryounasso
0
210
React inside basics: learn from “build own react"
ryounasso
0
220
抽象データ型について学んだ
ryounasso
0
430
開発効率向上のためのリファクタリングの一歩目の選択肢 ~コード分割~ / JJUG CCC 2024 Fall
ryounasso
0
4k
Clean Architecture by TypeScript & NestJS
ryounasso
0
1.2k
Fast API を用いた Web API の開発
ryounasso
1
620
テストゼロの個人開発プロジェクトにテストを導入した話
ryounasso
0
490
簡易 DI コンテナを作って DI コンテナを知る
ryounasso
1
1.4k
Other Decks in Programming
See All in Programming
さぁV100、メモリをお食べ・・・
nilpe
0
140
IBM Bobを活用したレガシーアプリの最新化
oniak3ibm
PRO
1
190
jQueryをバージョンアップする前に使いたいjQuery Migrate
matsuo_atsushi
0
430
Make SRE Operations Easier with Azure SRE Agent
kkamegawa
0
5.7k
Agentic UI
manfredsteyer
PRO
0
150
「AIで開発し、AIを届ける」をEvalでつなぐ 〜AIネイティブに始めるプロダクト開発の実践〜 / Connecting "Develop with AI, deliver AI" with Eval
rkaga
4
5k
RTSPクライアントを自作してみた話
simotin13
0
600
ローカルLLMでどこまでコードが書けるか -拡張版 / How much code can be written on a local LLM Extended
kishida
10
4k
エージェンティックRAGにAWSで入門しよう!
har1101
8
1.5k
Creating Composable Callables in Contemporary C++
rollbear
0
120
運用エージェントは "作る" から "育てる" へ - 記憶と自己進化の3層設計パターン / self-evolving-agents-three-layer-agent-design
gawa
12
3.7k
Lessons from Spec-Driven Development
simas
PRO
0
190
Featured
See All Featured
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.7k
First, design no harm
axbom
PRO
2
1.2k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
2.9k
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
200
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.8k
Designing Experiences People Love
moore
143
24k
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
370
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
170
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.7k
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.5k
Building Applications with DynamoDB
mza
96
7.1k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
Transcript
TypeScript コンパイラの 内側に片足入れる ryounasso
自己紹介 サイボウズ株式会社 kintone 新機能開発チーム SNS アカウント : @ryounasso TypeScript を触る機会
- 個人開発 (Next.js, React) - 業務 (React) 人生初 LT で緊張してます...
このスライドで目指すところ 1. ざっくりと処理の流れがわかる 2. それぞれの処理で、メインで動く関数とファイルがわかる TypeScript へのコントリビュートの足がかりに...!! > Good First
Issue Issues · microsoft/TypeScript · GitHub 25件ほどあった
TypeScript はそのまま動かない TypeScript はブラウザや Node.js など JavaScript の実行環境で動作させるために JavaScript にコンパイルする必要がある
TypeScript のコンパイラのソースは src/compiler フォルダ以下にある > https://github.com/Microsoft/TypeScript/tree/main/src/compiler 主要なファイルは以下の通り - scanner.ts - parser.ts - binder.ts - checker.ts - emitter.ts
大まかな流れ 字句解析 構文解析 識別子の 結合 型 チェック トランス パイル ソース
ファイル 出力 AST の作成
- Abstract Syntax Tree (抽象構文木) のこと - コードをパースして、ソースコードを意味的に表す木構造のこと - 端的にいうとコードを表すオブジェクト
AST とは 字句解析 構文解析 識別子の 結合 型 チェック トランス パイル AST の作成
字句解析 (scanner.ts) • 字句解析を行う • ソースコードをトークンに分割する。 • scan がメインの関数 •
Scanner は createScanner で生成される。 • scan を実行すると、スキャン中の位置や現在のトークンの詳細などを更新す る • Parser によって内部的に制御される • parser.ts でシングルトンの scanner が生成される (生成コスト削減) 字句解析 構文解析 識別子の 結合 型 チェック トランス パイル AST の作成
字句解析 (scanner.ts) // Sample usage initializeState(` var foo = 123;
`.trim()); // Start the scanning var token = scanner.scan(); while (token != ts.SyntaxKind.EndOfFileToken) { let currentToken = ts.formatSyntaxKind(token); let tokenStart = scanner.getStartPos(); token = scanner.scan(); let tokenEnd = scanner.getStartPos(); console.log(currentToken, tokenStart, tokenEnd); } VarKeyword 0 3 Identifier 3 7 FirstAssignment 7 9 FirstLiteralToken 9 13 SemicolonToken 13 14 字句解析 構文解析 識別子の 結合 型 チェック トランス パイル AST の作成
構文解析 (parser.ts) • 構文解析を行う • createSourceFile がメインの関数 • createParser で生成される
シングルトンとして実装されている 主にやっていることは、 1. ソースコードをトークンに分割 (scanner) 2. 文法規則に従って、AST を作成する 字句解析 構文解析 識別子の 結合 型 チェック トランス パイル AST の作成
var sourceCode = ` var foo = 123; `.trim(); var
sourceFile = ts.createSourceFile('foo.ts', sourceCode, ts.ScriptTarget.ES5, true); ----- /** createSourceFileの中で **/ result = Parser.parseSourceFile(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes, ScriptKind.JSON, noop, jsDocParsingMode); ----- printAllChildren(sourceFile); SourceFile 0 14 ---- SyntaxList 0 14 -------- VariableStatement 0 14 ------------ VariableDeclarationList 0 13 ---------------- VarKeyword 0 3 ---------------- SyntaxList 3 13 -------------------- VariableDeclaration 3 13 ------------------------ Identifier 3 7 ------------------------ FirstAssignment 7 9 ------------------------ FirstLiteralToken 9 13 ------------ SemicolonToken 13 14 ---- EndOfFileToken 14 14 構文解析 (parser.ts) 字句解析 構文解析 識別子の 結合 型 チェック トランス パイル AST の作成
識別子の結合 (bind.ts) • AST を読み取り、変数・関数などの宣言や定義を発見し、 代入先となる識別子と代入される値をバインドする • bindSourceFile がメインの関数 •
createBinder で生成される 主にやっていることは 1. AST の巡回 2. シンボルの作成 ソースコードの識別子 (変数や関数名など)に関する情報を持つオブジェクト 3. スコープの解決 4. 型情報の収集 字句解析 構文解析 識別子の 結合 型 チェック トランス パイル AST の作成
識別子の結合 (bind.ts) const msg: string = "Hello, world"; welcome(msg); function
welcome(str: string) { console.log(str) } Global Scope msg declared line 0 flags: BlockSopedVariable welcome declared line 3 flags: Function welcome Function Scope parent Global Scope str declared line 3 flags: BlockScopedVariable 字句解析 構文解析 識別子の 結合 型 チェック トランス パイル AST の作成
型チェック (checker.ts) tsc の中枢 コードの量がすごい...! (Github 上では多すぎて表示されなかった...) バインディングされた情報を元に、変数の型推論、型の整合性のチェック、 型のアサーションの確認などを行う。 checkSourceFile
がメインの関数 字句解析 構文解析 識別子の 結合 型 チェック トランス パイル AST の作成
型チェック (checker.ts) const msg: string = "Hello, world"; (簡略化した AST)
SourceFile └─ VariableStatement ├─ constKeyword └─ DeclarationList ├─ msg ├─ ColonToken ├─ StringKeyword ├─ EqualsToken └─ StringLiteral └─ "Hello World" 字句解析 構文解析 識別子の 結合 型 チェック トランス パイル AST の作成
型チェック (checker.ts) const msg: string = "Hello, world"; (簡略化した AST)
SourceFile └─ VariableStatement ├─ constKeyword └─ DeclarationList ├─ msg ├─ ColonToken ├─ StringKeyword ├─ EqualsToken └─ StringLiteral └─ "Hello World" 字句解析 構文解析 識別子の 結合 型 チェック トランス パイル AST の作成
トランスパイル (emitter.ts) 最後に、TypeScript コードを JavaScript コードにトランスパイルする emitFiles がメインの関数 JavaScript はバージョンによって使える文法が大きく変わる。
トランスパイルのために、transformer を使用 src/compiler/transformers フォルダ以下に、 それぞれES版に対するトランスフォーマー等が存在している 流れは以下の通り 1. getTransformers で適用する transformer の配列を取得 2. emitFiles で JavaScript コードにトランスパイル 字句解析 構文解析 識別子の 結合 型 チェック トランス パイル AST の作成
トランスパイル (emitter.ts) JavaScript では型情報が不要になる (transformers) const msg: string = "Hello,
world"; SourceFile └─ VariableStatement ├─ constKeyword └─ DeclarationList ├─ msg ├─ ColonToken ├─ StringKeyword ├─ EqualsToken └─ StringLiteral └─ "Hello World" const msg: string = "Hello, world"; SourceFile └─ VariableStatement ├─ constKeyword └─ DeclarationList ├─ msg ├─ EqualsToken └─ StringLiteral └─ "Hello World" 字句解析 構文解析 識別子の 結合 型 チェック トランス パイル AST の作成
まとめ 字句解析 scanner.ts scan 構文解析 parser.ts createSourceFile 識別子の結合 bind.ts bindSourceFile
ソース ファイル 出力 型チェック checker.ts checkSourceFile トランスパイル emitter.ts emitFiles
参考記事 - TypeScriptコンパイラの内側 - TypeScript Deep Dive 日本語版 (gitbook.io) -
https://www.youtube.com/watch?v=X8k_4tZ16qU&list=PLYUbsZda9oHu- EiIdekbAzNO0-pUM5Iqj&index=5 - https://qiita.com/eloy/items/9d0d8227121a1dcbdf71 - https://github.com/microsoft/TypeScript