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
1k
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
270
駆け足で Google から学ぶテスト設計の指針
ryounasso
0
210
React inside basics: learn from “build own react"
ryounasso
0
230
抽象データ型について学んだ
ryounasso
0
440
開発効率向上のためのリファクタリングの一歩目の選択肢 ~コード分割~ / JJUG CCC 2024 Fall
ryounasso
0
4.2k
Clean Architecture by TypeScript & NestJS
ryounasso
0
1.2k
Fast API を用いた Web API の開発
ryounasso
1
630
テストゼロの個人開発プロジェクトにテストを導入した話
ryounasso
0
500
簡易 DI コンテナを作って DI コンテナを知る
ryounasso
1
1.4k
Other Decks in Programming
See All in Programming
その節約、円になってますか?
isamumumu
0
590
AI時代に設計が 最大の生産性レバーになる 意図駆動開発とデータを消さない設計|Don't Delete Your Data or Your Intent — Design as the Deepest Lever in the AI Era
tomohisa
0
120
GDG Korea Android: 2026 I/O Extended ~ What's new in Android development tools
pluu
0
200
使用 Meilisearch 建立新聞搜尋工具
johnroyer
0
190
20260722_microCMSで考える、AI時代のコンテンツ運用設計
yosh1
0
170
複数の Claude Code が"放置"されてしまう問題をCLI ダッシュボードを自作して解決した話
sumihiro3
0
580
コーディングルールの鮮度を保ちたい for SRE NEXT 2026 / keep-fresh-go-internal-conventions-sre-next-2026
handlename
0
160
Haskell/Servantを通してWebミドルウェアを捉え直す
pizzacat83
1
630
『コードを書く以外の』エンジニアリング〜課金基盤移行プロジェクト推進のためのTips4選
yuriko1211
0
560
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
350
仕様書を書く前にハーネスを作る - Agent Native開発は「探索を速く、判定を固く」
gotalab555
3
1.3k
FDEが実現するAI駆動経営の現在地
gonta
2
240
Featured
See All Featured
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2k
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.2k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
GraphQLとの向き合い方2022年版
quramy
50
15k
Typedesign – Prime Four
hannesfritz
42
3.1k
Music & Morning Musume
bryan
47
7.3k
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
500
[SF Ruby Conf 2025] Rails X
palkan
2
1.2k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.2k
The Spectacular Lies of Maps
axbom
PRO
1
880
The SEO Collaboration Effect
kristinabergwall1
1
510
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
11k
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