
こんにちは。UPSIDERでソフトウェアエンジニアをしている中田です。
2026年5月にオフラインで開催された TSKaigi 2026 に登壇させていただきました。タイトルは「TypeScriptの型はAIに届いているか? ── AIコーディングツール検証で見えた『届き方』の差」。本記事では、当日お話しした内容を補足も交えながらお伝えします。
スライド・実験データ・再現コマンドは末尾にリンクを貼っているので、合わせて見ていただけると嬉しいです。
発表の背景
自分は普段、Claude Code と Codex を行ったり来たりしながら TypeScript のコードを書いています。使っているうちにふと気になったのが、「このAIに、TypeScript の型はどこまで届いているんだろう?」という素朴な問いでした。
型エラーは届いていそう。でも、エディターでホバーしたときに見える推論型や、定義ジャンプで辿れる構造はどうか。少なくとも自分の感覚では「ツールによって明らかに違う」気がしていたのですが、これを Yes / No で語ると粒度が荒すぎるな、というのが出発点です。
そこで、「届く」をもう少し解像度高く整理し、各 AI コーディングツールがそのどこに接続しているのかを実機・公式ドキュメント・Issue を見ながら検証した結果と、そこから見えてきた実務上の示唆を発表しました。
「届く」を3レイヤーに整理
最初に提案したのは、AI から見た型情報を3つのレイヤーに分けて捉えるという見方です。
- Text ── ソースに書かれた型。型注釈・シグネチャ・JSDoc など、ファイルを読めば得られる情報
- Diagnostics ──
tscや lint が計算して返すエラー・警告 - Semantics ── ホバーの推論型、定義ジャンプ、参照、呼び出し階層など、型システムに問い合わせて初めて得られる情報。LSP が代表的な経路
このうち今回いちばん差が出るのは Semantics でした。TypeScript は構造的型付けや型推論が強いので、「ソースに書いてあること」と「型システムが知っていること」がズレやすい言語です。たとえば次のような関数。
export function buildConfig(env: Env) { return { ...defaults, ...env.overrides, resolvedAt: Date.now() }; } // hover → { apiUrl: string; retries: number; resolvedAt: number }
戻り値型は明示していないので Text として読んでも形は見えませんが、ホバーすると推論された具体型が見えます。これが Semantics で、Text や grep だけでは届きにくい情報です。
「型が届く」を Yes / No ではなく、どのレイヤーまで届いているか で見ると、ツール間の差がきれいに整理できます。
各ツールはどこにどう接続しているか
調査対象は Claude Code / GitHub Copilot CLI / Codex CLI / Cursor / Gemini CLI の5つ。観測時点は 2026-05-16 です。Text と Diagnostics はどこもだいたい取れるので省略して、Semantics への接続だけを比較表にまとめました。
| ツール | Semantics への経路 | 主な手段 |
|---|---|---|
| Claude Code | ◯ | goToDefinition / findReferences / hover などを実装・公開済み |
| GitHub Copilot CLI | ◯ | goToDefinition / findReferences / hover などを実装・公開済み |
| Codex CLI | ✗ | shell + grep。Semantics 系ツールはなし |
| Cursor | ✗ | grep + embedding search |
| Gemini CLI | ✗ | native 未実装 |
きれいに2グループに分かれました。Claude Code と Copilot CLI は、AI に Semantics へ届く経路をツールとして渡している。一方で Codex / Cursor / Gemini CLI は持っていない、というのが現状です。
届かない側で印象的だったコメント
特に印象的だったのが、Codex CLI の LSP 統合を求める Issue #8745 に対する、現 OpenAI の Eric Traut 氏(Python の LSP である Pyright の作者)のコメントでした。
"the language server protocol was not designed for coding agents."
"We've experimented with the idea, and it hasn't provided the benefits that I initially thought it might."
要約すると「LSP は coding agent 向けに設計されたものではない」「試してみたが期待したほどの効果はなかった」。LSP 実装のど真ん中にいた方が、エージェント側でも試したうえでこう発言している、というのが重要なシグナルだと感じました。
この発言と、実装として Codex が LSP を採用していないという事実を合わせて読むと、いまの Codex は「LSP には乗らない」という設計判断で動いている ──「Text + Diagnostics + シェル操作で押し切る方向にベットしている」── というのが自分の解釈です。
経路があるからといって、効くわけではない
ここまでで「Semantics への経路を持つツールと、持たないツール」の差は見えました。ただ、経路があるならそれで十分か、というとそう単純でもありません。発表の後半は、ここに焦点を当てました。
モデルは LSP より grep を好む
VS Code v1.110 のリリースノート でも、agent は grep を好みがちだという話に触れられています。
自分でも Claude Code ( claude-opus-4-7 (1M context) / プロンプトキャッシュ有効) で、5タスク × N=10 = 50 セッションの実験をしてみました。
- 何も指示しないと、50/50 で LSP は一度も呼ばれず grep だけで完結
CLAUDE.mdに「LSP優先」と書くと使ってくれるようになるが、タスクによっては指示を無視して grep を選ぶ
つまり、機能が存在することと、モデルが実際にそれを呼ぶことの間には、運用指示の段差がはっきりあります。
LSP が逆効果になる場面
さらに踏み込むと、「使えば常に効く」というわけでもありません。
たとえば HTTPException のような、コードベース内で名前衝突しないユニークな識別子の参照タスク (N=10) では、こうなりました。
| 手段 | 時間 | コスト | 正解度 |
|---|---|---|---|
grep 直行 |
7.5s | $0.05 | 1.00 |
| LSP 優先 | 15.6s | $0.12 | 0.99 |
LSP優先のほうが約2倍遅く、コストは約2.4倍。正解度はほぼ同じ。LSP ツールをロードし、シンボルを特定し、findReferences を引くまでの前準備コストがそのまま乗ってきます。
grep で十分に追える探索に対して機械的に LSP を優先すると、むしろ逆効果になりえる、というのが手元の観測です。同様の指摘は LSPRAG (2025) や RLCSF (2025) でもされていました。
でも LSP が刺さる場面はある
一方で、LSP が明確に効く場面もあります。
共通名のクラス Context の参照を全部洗い出すタスク (N=10) では、結果が逆転します。
| 手段 | 時間 | コスト | 正解度 |
|---|---|---|---|
grep で頑張る |
148s | $0.78 | 0.985 |
LSP findReferences |
72s | $0.41 | 0.998 |
Context のように一般的な名前のクラスは、grep だと React の Context や別パッケージの Context まで大量にヒットしてしまい、手作業で除外を繰り返しながら正解に到達することになります。一方 LSP の findReferences は、型でつながった参照だけを一発で返してくれる。
名前衝突しうるシンボル や、型でしか辿れない関係を追うタスク では、LSP の省力性がはっきり出ます。
補足:正解度は precision(誤検出の少なさ)と recall(取りこぼしの少なさ)の調和平均(F1)で、0〜1 のスコア。1 が最高です。
実務で、型をAIにどう届かせるか
ここまでの観測をふまえて、実務にどう落とすか。
自分が今意識しているのは、Semantics に頼るだけではなく、Text と設定でも届き方を整える という発想です。具体的には次の3つ。
- コード側でできること:公開 API の戻り値型を明示する/繰り返し使う型に名前を付ける/
asやanyを減らす。これだけで Semantics に問い合わせなくても Text として AI が読める範囲が広がります - エージェント設定:「常に LSP を優先しろ」ではなく、「名前衝突しやすい / 呼び出し階層を辿る系のタスクでは LSP を使え」という タスクで使い分ける指示 に寄せる
- 足りない経路は外付け:自分のメインツールが Semantics を持っていない場合、Serena のような外付け MCP で経路を足す選択肢もあります
見るべきは「使っているツールが LSP に対応しているか」ではなく、「タスクに応じて型を AI にどう届けるか」だと思っています。
結論
TypeScript の型は AI に届く。ただし、大事なのは 届くか ではなく どう届くか です。
- 単純な探索なら
grep + Diagnosticsで十分なことがある - 呼び出し階層 / rename / 曖昧名の追跡といったタスクでは Semantics の価値が大きい
- 実務で見るべきなのは、LSP 対応の有無ではなく、タスクに応じた届け方を持てるか
当日のこと
実はこれが初めての登壇でした。あの規模の会場で話すというのは想像していた以上の緊張感で、登壇直前は本当に落ち着かなかったです。
それでも最後まで形になったのは、ここまでしっかり準備してきたおかげだと思っています。準備が支えになる、というのを今回身をもって体感しました。
おわりに
今回の登壇に向けて検証や整理を進めるなかで、自分自身も AI と型の関係について学ぶことが多く、率直に「勉強になったな」というのが一番の感想です。
最後になりますが、TSKaigi スタッフのみなさん、聴いてくださったみなさん、本当にありがとうございました。
資料・参考リンク
当日のスライド
- 実験の生データ・集計・
CLAUDE.md全文・再現コマンド:gist.github.com/sh0o0/bdd9d0c - 主な一次資料:
- openai/codex Issue #8745 ── Codex の LSP 非採用 / Eric Traut コメント
- VS Code v1.110 release notes ── Copilot agent が grep を好む
- GitHub Docs: Using LSP servers with GitHub Copilot CLI
- Cursor Docs: Semantic & Agentic Search
- Cursor Forum #156751
- Gemini CLI の LSP 要望:Issue #2465 / Issue #6690
- LSPRAG (2025) ── 静的型言語ほど LSP の効果が強い
- RLCSF (2025) ── raw LSP は agent 向けに脆い
We Are Hiring !
UPSIDER は TypeScript × AI に本気で取り組んでいるチームです。法人カードを中心とした金融インフラを、フルスタック TypeScript で構築しています。Claude Code や Codex も日々の開発フローに組み込んでいて、「型を AI にどう届けるか」みたいな話を本気で議論できる仲間を募集中です。
少しでも興味を持ってくださった方は、ぜひカジュアル面談からどうぞ。
UPSIDER Engineering Deckはこちら📣