UPSIDER Tech Blog

TypeScriptの型はAIに届いているか? ── TSKaigi 2026 登壇レポート

こんにちは。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 の戻り値型を明示する/繰り返し使う型に名前を付ける/asany を減らす。これだけで Semantics に問い合わせなくても Text として AI が読める範囲が広がります
  • エージェント設定:「常に LSP を優先しろ」ではなく、「名前衝突しやすい / 呼び出し階層を辿る系のタスクでは LSP を使え」という タスクで使い分ける指示 に寄せる
  • 足りない経路は外付け:自分のメインツールが Semantics を持っていない場合、Serena のような外付け MCP で経路を足す選択肢もあります

見るべきは「使っているツールが LSP に対応しているか」ではなく、「タスクに応じて型を AI にどう届けるか」だと思っています。

結論

TypeScript の型は AI に届く。ただし、大事なのは 届くか ではなく どう届くか です。

  • 単純な探索なら grep + Diagnostics で十分なことがある
  • 呼び出し階層 / rename / 曖昧名の追跡といったタスクでは Semantics の価値が大きい
  • 実務で見るべきなのは、LSP 対応の有無ではなく、タスクに応じた届け方を持てるか

当日のこと

実はこれが初めての登壇でした。あの規模の会場で話すというのは想像していた以上の緊張感で、登壇直前は本当に落ち着かなかったです。

それでも最後まで形になったのは、ここまでしっかり準備してきたおかげだと思っています。準備が支えになる、というのを今回身をもって体感しました。

おわりに

今回の登壇に向けて検証や整理を進めるなかで、自分自身も AI と型の関係について学ぶことが多く、率直に「勉強になったな」というのが一番の感想です。

最後になりますが、TSKaigi スタッフのみなさん、聴いてくださったみなさん、本当にありがとうございました。

資料・参考リンク

当日のスライド

speakerdeck.com

We Are Hiring !

UPSIDER は TypeScript × AI に本気で取り組んでいるチームです。法人カードを中心とした金融インフラを、フルスタック TypeScript で構築しています。Claude Code や Codex も日々の開発フローに組み込んでいて、「型を AI にどう届けるか」みたいな話を本気で議論できる仲間を募集中です。

少しでも興味を持ってくださった方は、ぜひカジュアル面談からどうぞ。

herp.careers

herp.careers

UPSIDER Engineering Deckはこちら📣

speakerdeck.com