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
ts-morph実践:型を利用するcodemodのテクニック
Search
ypresto
May 24, 2025
Programming
1
710
ts-morph実践:型を利用するcodemodのテクニック
TSKaigi 2025
ypresto
May 24, 2025
Tweet
Share
More Decks by ypresto
See All by ypresto
状態と共に暮らす:ステートフルへの挑戦
ypresto
3
1.9k
Next.jsとNuxtが混在? iframeでなんとかする!
ypresto
3
3.6k
Cancel Next.js Page Navigation: Full Throttle
ypresto
1
3.2k
Next.js のページ遷移を全力で止める
ypresto
15
9.1k
TypeScriptの型とパフォーマンス (TSKaigi 2024)
ypresto
21
8k
アクセシビリティとE2Eテスト
ypresto
0
120
VS Codeのプロセスモデルとデバッグ方法 - パフォーマンスと安定性を支えるアーキテクチャ
ypresto
1
510
TypeScriptの型定義をPRする技術
ypresto
1
770
Other Decks in Programming
See All in Programming
オホーツクでコミュニティを立ち上げた理由―地方出身プログラマの挑戦 / TechRAMEN 2025 Conference
lemonade_37
1
430
JetBrainsのAI機能の紹介 #jjug
yusuke
0
180
新しいモバイルアプリ勉強会(仮)について
uetyo
1
240
AIコーディングエージェント全社導入とセキュリティ対策
hikaruegashira
15
9.3k
Workers を定期実行する方法は一つじゃない
rokuosan
0
140
Vibe coding コードレビュー
kinopeee
0
400
Advanced Micro Frontends: Multi Version/ Framework Scenarios
manfredsteyer
PRO
0
140
AI Agent 時代のソフトウェア開発を支える AWS Cloud Development Kit (CDK)
konokenj
6
1k
Flutterと Vibe Coding で個人開発!
hyshu
1
210
Claude Code で Astro blog を Pages から Workers へ移行してみた
codehex
0
170
「次に何を学べばいいか分からない」あなたへ──若手エンジニアのための学習地図
panda_program
3
710
The Niche of CDK Grant オブジェクトって何者?/the-niche-of-cdk-what-isgrant-object
hassaku63
1
740
Featured
See All Featured
Stop Working from a Prison Cell
hatefulcrawdad
271
21k
Making the Leap to Tech Lead
cromwellryan
134
9.5k
How STYLIGHT went responsive
nonsquared
100
5.7k
Making Projects Easy
brettharned
117
6.3k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
126
53k
YesSQL, Process and Tooling at Scale
rocio
173
14k
GitHub's CSS Performance
jonrohan
1031
460k
Visualization
eitanlees
146
16k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
30
2.2k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
16k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
161
15k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
50
5.5k
Transcript
ts-morph実践: 型を利用するcodemodの技巧 テクニック 2025/05/23:TSKaigi 2025 @ 東京・神田 ypresto (@yuya_presto)
ypresto © LayerX Inc. LayerX バクラク事業部 (2024-01〜) プロダクト開発部 債権債務チーム Software
Engineer TypeScriptへのコントリビュート歴あり 宣伝の時間なんてないので採用サイトを 2
CfP応募後に tsgoが発表された! Compiler APIが塞がる可能性・・・ © LayerX Inc. 3
終 制作・著作 LayerX ったかと思ったけど大丈夫かも!? 中の人の回答 © LayerX Inc. 4
codemod © LayerX Inc. AST (抽象構文木) を通して、機械的にコードを書き換える DOMツリーとHTMLの関係 = ASTとコードの関係、と考えると楽。
ASTのNodeを探して書き換えると、コードが書き換わる jscodeshift:Meta製 例えばMUIのアップグレードのための @mui/codemod で使われている ts-morph: 型が使える← 今日 TypeScript Compiler API をゴリゴリとwrapしたライブラリ 5
ts-morphを使う利点 jscodeshiftや、ラップされていないCompiler APIと比べて・・・ © LayerX Inc. node.findReferencesAsNodes() でエディタのように参照元を探せる node.getType() で型情報をチェックできる
getTypeNode() で型注釈もすぐ取れる node.replaceWithText("const foo = 1") のように、 AST Nodeを組み立てず文字列で書き込める => 楽で安全な書き換え 6
具体例1: consoleの呼び出しをloggerに書き換え あちこちにはびこる「とりあえずconsole.error(e)」を退治したい © LayerX Inc. 7
Find And Replaceだと不安がある理由 © LayerX Inc. console.error(e) → logger.caught(e) 8
© LayerX Inc. console.error(e) → logger.caught(e) / 実装 9
© LayerX Inc. console.error(e) → logger.caught(e) / 実装 10
© LayerX Inc. console.error(e) → logger.caught(e) / 実装 11
Cannot find name 'logger' sourceFile.organizeImports() せずにimportを足すのがむずい。 そもそもimport { A }
from B のAとBをASTで扱うのがめんどい。 © LayerX Inc. console.error(e) → logger.caught(e) 12
しゃーなしでヘルパー作りました しばらくしたら公開されます。 © LayerX Inc. 13
具体例2: noImplicitAny: false を倒したい © LayerX Inc. 14
具体例2: noImplicitAny: false を倒したい 理論上は可能 (たぶん) © LayerX Inc. 15
型注釈を自動でつけるには © LayerX Inc. noImplicitAny: false を倒したい 16
1. 引数に使われた型を集める © LayerX Inc. noImplicitAny: false を倒したい 17
2. 集めた型をこねて丸める Type Wideningがないと、 let foo = 1 に 2
が入らなくなります。 © LayerX Inc. noImplicitAny: false を倒したい 18
ts-morphもCompiler APIも、型を作る方法がない 全くないからしゃーなしでchecker.ts読んで拾ってきた。 © LayerX Inc. noImplicitAny: false を倒したい 19
実装 © LayerX Inc. noImplicitAny: false を倒したい 20
意外とできる © LayerX Inc. 21
おわり © LayerX Inc. ts-morphで型を使うと無限の可能性がある おもしろい悪事ができそう ASTの知識が必要 https://astexplorer.net/ を片手にやりましょう ヘルパーを用意して楽にしましょう
今日のコードはここに上げています https://github.com/ypresto/ts-morph-toybox あとでnpmへ 22
ここから先は喋らないやつ © LayerX Inc. 23
あと:AI来るともcodemod死せず codemodの弱点:ASTの知識が必要、書くのが大変 © LayerX Inc. AIは、プロジェクト全体をまとめて読めるわけじゃない (Context Window) codemodは、プロジェクト全体に決定論的に同じ内容を高速に当てら れる
なので、codemodは引き続き有効。できればAIに書かせたい。 24
例えばenabled: trueを全部の呼び出し元に追加したいとき © LayerX Inc. 25
メソッドチェーンの呼び出しを探す © LayerX Inc. { baz: () => { ...
} } のbazの呼び出しが、foo.bar.baz(1) になっていると き 愚直に祖先のcallを取ると、boo(foo.bar.baz) の boo() が取れてしまう ASTが読めると baz (Identifier) → foo.bar.baz (Property Access Expression) → foo.bar.baz(...) (Call Expression) とできる https://astexplorer.net/ を片手にやる 26
理解は容易、 実装は困難。 © LayerX Inc. 27