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
JavaScript実装の自作プログラミング言語をTypeScript実装に移行した話
Search
Keisuke Ikeda
May 22, 2026
Technology
210
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
JavaScript実装の自作プログラミング言語をTypeScript実装に移行した話
https://2026.tskaigi.org/talks/48
Keisuke Ikeda
May 22, 2026
More Decks by Keisuke Ikeda
See All by Keisuke Ikeda
技術検証結果の整理と解析をAIに任せよう!
keisukeikeda
0
190
Docコメントで始める簡単ガードレール
keisukeikeda
1
190
初めてのLisp自作譚
keisukeikeda
0
50
tsconfigのオプションで変わる型世界
keisukeikeda
2
240
Other Decks in Technology
See All in Technology
hookで自作する Claude Code の「実況ボード」
shinyasaita
2
270
魔法少女がClaude Codeを監視する / ccportal-deck
noriyukitakei
3
110
【5分でわかる】セーフィー エンジニア向け会社紹介
safie_recruit
0
54k
全社に広がるMCPサーバーを、 どう安全に管理するか MCPass開発の舞台裏
mtpooh
3
220
AWSとGitHub Actionsの責任境界と 組織で安全に使用する取り組み
nealle
1
240
Data Hubグループ 紹介資料
sansan33
PRO
0
3.2k
EMの役割で 変わったこと・変わらなかったこと
sansantech
PRO
1
220
All About Sansan – for New Global Engineers
sansan33
PRO
1
1.5k
顧客の要望は2次情報である 〜アンテナを張るFDEの構造論〜
noriakioji
5
1.1k
どんな手を使っても絶対間に合わせるスケジューラ
asari194617
0
1.5k
アクセスキー流出時の対応で再認識した攻撃側と防御側の非対称性について
kazzpapa3
1
490
[DroidKaigi 2026] Making UI specifications visible: Android UI development in the AI agent era supported by Compose Screenshot Testing and galleries
syarihu
0
210
Featured
See All Featured
The SEO Collaboration Effect
kristinabergwall1
1
540
Why You Should Never Use an ORM
jnunemaker
PRO
61
10k
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
390
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
6
1.2k
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
680
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
460
Automating Front-end Workflow
addyosmani
1369
210k
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.5k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
3k
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2.2k
Believing is Seeing
oripsolob
1
200
Transcript
+BWB4DSJQU࣮ͷ ࣗ࡞ϓϩάϥϛϯάݴޠΛ 5ZQF4DSJQU࣮ʹҠߦͨ͠ ,FJTVLF*LFEB 54,BJHJ !JLF@LFJDIBO
自己紹介 02/14 ɾ౦ژͱؔʢେࡕ&ژʣͷ2ڌੜ׆த ɾTSKaigi 2025,2026 / ϑϩϯτΤϯυΧϯϑΝϨϯεؔ 2025,2026 ɹ3FBDU5PLZPϑΣεͷελοϑ ɾษڧձ/ΧϯϑΝϨϯεେ͖Ϛϯ,
ΠϕϯτதͷπΠʔτ͕͏Δ͍͞ ɾࠓɺ࢈·Εͨ໑ͱै໑͕͔Θ͍͍ͱࢥ͍ͬͯΔ !JLF@LFJDIBO ,FJTVLF*LFEB
tsconfigに向き合おう! 03/14 ͜ͷൃදͰߦ͏͜ͱ ✅ ͢Δ͜ͱ ɾJS → TSҠߦͷ࣮ମݧ ɾݴޠ࣮ͱ͍͏υϝΠϯͰͷTSͷخ͔ͬͨ͠ɺͭ·͍ͮͨ 🚫
ɾࣗ࡞ͨ͠ݴޠɺࣗ࡞ͷϞσϧʹͨ͠ݴޠɺݴޠॲཧܥͷৄ͍͠ ɾTypeScript ͷجຊతͳ͍ํͷઆ໌ !JLF@LFJDIBO
前提知識 04/14 Έͳ͞Μ ϓϩάϥϛϯάݴޠ ݴޠॲཧܥ ࣗ࡞ͨ͜͠ͱ͋Γ·͔͢ʁ !JLF@LFJDIBO
前提知識 05/14 ɾ1958 John McCarthy ͞ΜͷจͰൃද ɾؔܕϓϩάϥϛϯάݴޠͷϧʔπ ɾߏจ͕ඇৗʹγϯϓϧɿS ࣜʢલஔه๏ʣ ɹˠ
ࣗ࡞ϓϩάϥϛϯάݴޠɾݴޠॲཧܥͷೖʹ࠾༻͞Ε͍͢ ࣗ࡞ݴޠͷϞσϧ-JTQʹ͍ͭͯ !JLF@LFJDIBO (+ 1 2) (* (+ 3 4) (- 10 (* 2 3)))
前提知識 06/14 ίʔυ͕ಈ͘·Ͱ !JLF@LFJDIBO ιʔεจࣈྻ (* (+ 3 4) (-
10 (* 2 3))) ࣈ۟ղੳʢLexerʣ τʔΫϯྻ [ *, (, +, 3, 4, ), (, -, 10, ... ] ߏจղੳʢParserʣ ASTʢߏʣ * + - 3 4 10 ... ධՁʢEvaluatorʣ 28
JSで苦しんだ話 07/14 +4Ͱۤ͠Μͩ index.js const eval = (node, env) =>
{ // node は以下のいずれか: // number | string | symbol(識別子)| list | nil // // JS は引数に型を持たない // 型の検証はすべて実行時 };
JSで辛かった話 08/14 ܕͷෆҰக͕ index.js const eval = (node, env) =>
{ if (node.type === "number") return node.value; if (node.type === "list") return apply(evaluate(node.car, env), node.cdr); // symbol(識別子)の処理が抜けている // return 文なし → undefined を返す // → apply の第1引数が undefined に // → 再帰の数段後で TypeError };
TSに移行して 09/14 !JLF@LFJDIBO ܕʹΑΔදݱ // BNF <value> ::= <number> |
<string> | <symbol> | <list> | nil // TypeScript type LispValue = number | string | Symbol | Cons | null; ɾBNFʢBackus-Naur Formʣɿݴޠͷจ๏Λܗࣜతʹهड़͢Δه๏ ɾBNF ͷ"|" TypeScript ͷϢχΦϯܕܕʢSum TypeʣΛදݱ ɾݴޠ࣮ͱ͍͏ෳࡶͳυϝΠϯʹରԠ͍͢͠
TSに移行して 10/14 !JLF@LFJDIBO 5ZQF4DSJQUͷ/BSSPXJOHʢ௨ৗ࣌ʣ index.ts // ローカル変数:TypeScript が正確に追跡できる let token:
string | null = null; token = "hello"; token.toUpperCase(); // ✓ string と確定 token = null; token.toUpperCase(); // ✗ コンパイルエラー:null の可能性
TSに移行して 11/14 !JLF@LFJDIBO 5ZQF4DSJQUͷ/BSSPXJOHʢDMBTTʣ index.ts class Lexer { private token:
string | null = null; private readNext(): void { this.token = "hello"; // フィールドを書き換える副作用 } next(): void { this.token = null; // TypeScript:token は null と記録 // ... // readNext() の中身は解析しない // → this.token が書き換わることを TypeScript は追跡できない } }
TSに移行して 12/14 !JLF@LFJDIBO 54Ͱۤ͠Μͩ index.ts class Parser { private current:
LispValue = null; // 完成したトークンを格納 private state: number = 0; private consume(): void { // 1文字読み進め、トークンが完成したら this.current に格納 } nextToken(): LispValue { this.current = null; // ① TypeScript:current は null と記録 while (!this.done()) { if (this.current !== null) break; // ② TypeScript:常に false と警告 this.consume(); // ③ this.current を書き換えるが追跡されない } return this.current; } }
TSに移行して 13/14 !JLF@LFJDIBO 54ͱͯ͠ਖ਼͍͠001ઃܭ index.ts class Parser { private current:
LispValue = null; // 完成したトークンを格納 private state: number = 0; private consume(): void { // 1文字読み進め、トークンが完成したら this.current に格納 } nextToken(): LispValue { this.current = null; // ① TypeScript:current は null と記録 while (!this.done()) { if (this.current !== null) break; // ② TypeScript:常に false と警告 this.consume(); // ③ this.current を書き換えるが追跡されない } return this.current; } }
まとめ 14/14 !JLF@LFJDIBO ·ͱΊ ɾ+4࣮࣌ܕͷෆҰக͕VOEFGJOFEͱͯ͠੩͔ʹͤ͞ΔɻΤϥʔͷ ɹݪҼՕॴͱൃੜՕॴ͕ͣΕͯਏ͍😭 ɾจ๏هड़ʢ#/'ʣͱϢχΦϯܕܕʢ4VN5ZQFʣͱͯ͠ࣅͨߏΛ ɹ࣋ͭɻܕʹΑΔ੍Ͱ࣮ߦલʹʹؾ͚ͮΔ😎 ɾ/BSSPXJOHϝιουݺͼग़͠ޙͷϑΟʔϧυมߋΛ͠ͳ͍ɻ001 ɹͷঢ়ଶཧͱিಥ͢Δ😵
宣伝 ϑϩϯτΤϯυΧϯϑΝϨϯεؔ 2026 ଓใSNSͰ֬ೝͯ͠ʙ X note