Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
TypeScript_コンパイラの内側に片足を入れる
Search
ryounasso
November 23, 2023
Programming
1.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
300
駆け足で Google から学ぶテスト設計の指針
ryounasso
0
260
React inside basics: learn from “build own react"
ryounasso
0
250
抽象データ型について学んだ
ryounasso
0
500
開発効率向上のためのリファクタリングの一歩目の選択肢 ~コード分割~ / JJUG CCC 2024 Fall
ryounasso
0
4.4k
Clean Architecture by TypeScript & NestJS
ryounasso
0
1.2k
Fast API を用いた Web API の開発
ryounasso
1
650
テストゼロの個人開発プロジェクトにテストを導入した話
ryounasso
0
520
簡易 DI コンテナを作って DI コンテナを知る
ryounasso
1
1.4k
Other Decks in Programming
See All in Programming
ハーネス設計入門 〜 基礎知識の整理から実務へのステップアップ 〜
kinopeee
21
21k
phperだってパンチカードでコーディングしたい
o0h
PRO
0
240
複雑なUIコンポーネントとの ⻑い付き合い⽅:波及するバグからテスト戦略を経て、安全な再設計へ
mixplace
0
250
機械に任せるテスト、人が見るテスト ⽣成AIで引き直した、運⽤保守フェーズの線引き
dske104
0
170
The Rails Doctrine Decade
koic
2
540
Ghostty + Neovimで作る 透明でカッコ良い開発環境
j341nono
0
150
ジョジョの世界をXRで再現する
mofurune
0
140
仕様駆動開発による爆速プロダクト開発 / Bakusoku Spec Driven Development
kobakei
0
210
技術的負債を組織課題として解く-増えすぎたマイクロサービスとの戦い-
reimaru
1
2.9k
そのリトライ、死んだコネクションを使い回していませんか ── GoのHTTPクライアントとHTTP/2を実プロダクト障害から学び直す
myus4a
0
410
AI が書く Go コードの品質を劇的に向上させる Linter: “declscope”
mpyw
0
480
Unity6 URPによる海底をテーマにしたVJシステムの解説 | Unity Shader 完全に理解した 勉強会
gam0022
0
340
Featured
See All Featured
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
1
550
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.4k
Designing for Timeless Needs
cassininazir
1
520
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
63
46k
Thoughts on Productivity
jonyablonski
76
5.4k
We Are The Robots
honzajavorek
0
390
Navigating Team Friction
lara
192
16k
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
68
58k
Into the Great Unknown - MozCon
thekraken
41
2.8k
Exploring anti-patterns in Rails
aemeredith
4
530
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.8k
The Invisible Side of Design
smashingmag
301
52k
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