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
190
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
170
Docコメントで始める簡単ガードレール
keisukeikeda
1
170
初めてのLisp自作譚
keisukeikeda
0
39
tsconfigのオプションで変わる型世界
keisukeikeda
2
230
Other Decks in Technology
See All in Technology
從開發到部署全都交給 AI:實作 AI 驅動的自動化流程
appleboy
0
170
技術・能力を向上する原理原則 #きのこセッションa #きのこ2026
bash0c7
0
140
千葉での単身赴任からAWSをやり続け、千葉に戻ってきた話
yama3133
1
120
Flow 不死:AI 時代 DevOps 的不變本質
cheng_wei_chen
2
530
螺旋型キャリアの生存戦略 / kinoko-conf2026
rakus_dev
1
1.1k
AIに障害切り分けを全部やってもらった。 。 。 。
estie
0
200
「ビジネスがわかるエンジニア」とは何か?
ryooob
0
330
Deep Data Security 機能解説
oracle4engineer
PRO
2
220
起点・思考・出力で分解する 〜PM業務の自動化設計〜
kazu_kichi_67
2
1.1k
AIエージェントとPhysical AIが拓く製造業の変革(ハノーバーメッセリキャップ)
iotcomjpadmin
0
150
[AWS Summit Japan 2026]迷っているあなたへ_小さな一歩が、やがて自分を助けてくれる
sh_fk2
2
420
FPGAの開発コンペでZephyrを使ってみた
iotengineer22
0
210
Featured
See All Featured
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
480
Building Applications with DynamoDB
mza
96
7.1k
Art, The Web, and Tiny UX
lynnandtonic
304
22k
BBQ
matthewcrist
89
10k
How to build a perfect <img>
jonoalderson
1
5.7k
Believing is Seeing
oripsolob
1
150
The Mindset for Success: Future Career Progression
greggifford
PRO
0
370
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
55
3.4k
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
170
Measuring & Analyzing Core Web Vitals
bluesmoon
9
870
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
210
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