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
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
ryounasso
November 23, 2023
Programming
970
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
240
駆け足で Google から学ぶテスト設計の指針
ryounasso
0
200
React inside basics: learn from “build own react"
ryounasso
0
220
抽象データ型について学んだ
ryounasso
0
420
開発効率向上のためのリファクタリングの一歩目の選択肢 ~コード分割~ / JJUG CCC 2024 Fall
ryounasso
0
4k
Clean Architecture by TypeScript & NestJS
ryounasso
0
1.1k
Fast API を用いた Web API の開発
ryounasso
1
620
テストゼロの個人開発プロジェクトにテストを導入した話
ryounasso
0
490
簡易 DI コンテナを作って DI コンテナを知る
ryounasso
1
1.4k
Other Decks in Programming
See All in Programming
AutonomyとControlのあいだ:Graflowで記述するAIエージェント協調
myui
0
110
今さら聞けないCancellationToken
htkym
0
220
プロパティの順序で型推論が壊れる!? TypeScript6.0の修正からContext-Sensitivityの仕組みを追う
bicstone
2
1.3k
AI 時代のソフトウェア設計の学び方
masuda220
PRO
29
12k
Composerを使ったサプライチェーン攻撃の様子を眺めてみる #phpstudy
o0h
PRO
2
220
軽量Java基盤の設計 DIコンテナに頼らない、長期保守と1秒起動の実現 JJUG CCC 2026 Spring
macha64
0
450
Language Server 使ってる? 〜VSCode と Zed の場合〜 / Are you using a Language Server? ~For VS Code and Zed~
handlename
0
750
oxlintはeslint/typescript-eslintを置き換えられるのか
shomafujita
2
320
TypeScript+Orvalで実現する型安全かつ堅牢でスケーラブルなマルチチャネル通知基盤 / TSKaigi Night talks ~after conference~
d0riven
0
290
フロントエンドとバックエンドで「1文字」を揃えよう
youkidearitai
PRO
0
200
LLM Plugin for Node-REDの利用方法と開発について
404background
0
160
セキュリティの専門家じゃなくてもできる。「セキュリティ意識」をアップデートして サプライチェーン攻撃への耐性を高めよう。
tk3fftk
5
630
Featured
See All Featured
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
118
120k
AI in Enterprises - Java and Open Source to the Rescue
ivargrimstad
0
1.3k
Art, The Web, and Tiny UX
lynnandtonic
304
22k
Prompt Engineering for Job Search
mfonobong
0
330
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
200
Deep Space Network (abreviated)
tonyrice
0
160
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
22k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
1
2.7k
Optimising Largest Contentful Paint
csswizardry
37
3.7k
Ethics towards AI in product and experience design
skipperchong
2
300
GraphQLとの向き合い方2022年版
quramy
50
15k
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