TypeScript 7はなぜGoで書き直されたのか — 10倍高速化の技術的背景

に公開

TypeScriptコンパイラが「Go」で書き直された衝撃

150万行のコードを持つVS Codeプロジェクト。そのTypeScriptビルドが、77.8秒から7.5秒に短縮されました。

10.4倍の高速化です。

2025年3月11日、TypeScriptの生みの親であるAnders Hejlsbergが公式ブログで発表した内容は、フロントエンド開発の常識を覆すものでした。TypeScript 7では、コンパイラの実装言語がTypeScript(JavaScript)からGoに完全移行します。これにより、ビルド速度の10倍高速化、エディタ起動の8倍高速化、メモリ使用量の50%削減が実現されます。

この記事では、3つの軸からこの変化を読み解いていきます。

  1. なぜGoが選ばれたのか — RustでもC++でもない理由
  2. どう速くなるのか — 10倍高速化の技術的な仕組み
  3. 開発現場への影響 — 今すぐ・近い将来・中長期で何が変わるか

対象読者は、TypeScriptを日常的に使っているフロントエンド/バックエンドエンジニアの方です。コンパイラの内部構造に詳しくなくても理解できるよう、順を追って説明していきます。

なぜ「Go」だったのか — 言語選定の技術的根拠

結論から言うと、Goが選ばれた最大の理由は「既存コードベースとの構造的な類似性」です。パフォーマンスだけなら他の言語でも実現できます。しかし、移植の現実性という観点でGoが圧倒的に有利でした。

「ポート」と「リライト」の違い

ここで重要な区別があります。「ポート(port)」とは、既存のロジックと構造をそのまま別の言語で表現すること。「リライト(rewrite)」とは、設計そのものをゼロから作り直すことです。

TypeScriptチームのRyan Cavanaughはこう述べています。

「最終的に2つの選択肢がありました。Rustで完全なスクラッチリライトを行い、数年かけて互換性の保証が困難なバージョンを作るか、Goでポートを行い、1年ほどで極めて互換性の高いものを作るか」

TypeScriptチームが選んだのは、確実に成果を出せる「ポート」の道でした。

Goと既存コードベースの親和性

Anders Hejlsbergは、既存のTypeScriptコンパイラの特徴をこう説明しています。

「既存のコードベースはすべて関数とデータ構造で構成されている。クラスは使っていない」

この構造が、Goの「関数+構造体」というパラダイムに自然にマッチしました。Ryan Cavanaughも「慣用的なGoは、既存のTypeScriptコードベースのコーディングパターンに非常によく似ている」と指摘しています。

以下の図で、言語候補を比較してみます。

図: 言語候補の比較。Goは4つの選定基準すべてで適合しています

Rustが選ばれなかった具体的な理由

Rustの性能がGoに劣るから、ではありません。パフォーマンステストでは、RustとGoは「誤差の範囲内(within the margin of error)」という結果でした。

問題はボローチェッカー(borrow checker)です。ボローチェッカーとは、Rustがコンパイル時にメモリ安全性を保証するための仕組みです。TypeScriptコンパイラの内部では循環的なデータ構造が多用されています。Rustでこれを表現するには「メモリ管理、ミューテーション、データ構造、ポリモーフィズム、遅延評価の根本的な再考」が必要になります。

つまり、Rustを選ぶと「ポート」ではなく「リライト」になってしまうのです。

GCが問題にならない理由

「GoにはGC(ガベージコレクション)があるから遅いのでは?」という疑問は自然なものです。しかし、コンパイラというユースケースでは、GCのオーバーヘッドはほぼ無視できます。

Ryan Cavanaughはその理由をこう説明しています。

「非バッチシナリオでは、初期に割り当てたもの(AST等)のほとんどがプログラムの全ライフタイムにわたって生存する」

AST(抽象構文木)とは、ソースコードを解析して得られる木構造のデータです。コンパイラの主要なデータは、一度作ったら最後まで使い続けます。頻繁に作って捨てるわけではないので、GCの出番がそもそも少ないのです。

開発のタイムライン

Anders Hejlsbergは2024年8月にプロトタイピングを開始しました。わずか6ヶ月で機能の80%を移植完了。2025年3月11日に公式発表「A 10x Faster TypeScript」が行われました。

このスピード感こそ、「ポート」戦略の成果です。リライトであれば、数年単位のプロジェクトになっていたことは間違いありません。

アーキテクチャ比較 — 旧TypeScript vs 新TypeScript

結論から言うと、新旧のコンパイラは論理的には同じパイプラインを持ちます。変わったのは、そのパイプラインが動く「土台」です。シングルスレッド+JSランタイムの制約が取り払われ、ネイティブバイナリによる並行処理が可能になりました。

旧アーキテクチャ(コードネーム: Strada)

現行のTypeScriptコンパイラは「セルフホスティング」と呼ばれる構造を持っています。セルフホスティングとは、TypeScriptコンパイラ自体がTypeScriptで書かれている状態のことです。

処理の流れはこうなっています。

  1. TypeScriptで書かれたコンパイラのコードをJavaScriptにコンパイル
  2. そのJavaScriptをNode.js(V8エンジン)上で実行
  3. ユーザーのTypeScriptコードを処理

この構造には根本的な制約があります。Node.jsのイベントループは基本的にシングルスレッドです。Worker Threadsで並列化する方法もありますが、V8インスタンスごとにメモリフットプリントが大きく、スケーラビリティに限界があります。

新アーキテクチャ(コードネーム: Corsa)

新しいGo版コンパイラのコードネームは「Corsa」です。イタリア語で「レース」を意味します。リポジトリは github.com/microsoft/typescript-go として公開されており、オープンソースで開発が進んでいます。

図: 旧アーキテクチャと新アーキテクチャのビルドパイプライン比較。論理的な処理フローは同じですが、各フェーズで並列処理が可能になっています

並行処理の仕組み

Go版コンパイラの並行処理は、フェーズごとに異なるアプローチを取っています。

パースとバインド(Phase 1) は「embarrassingly parallel(恥ずかしいほど並列化が容易)」な処理です。各ファイルは独立しているため、32コアのマシンなら32ファイルを同時に処理できます。結果のAST(抽象構文木)は不変(immutable)なので、同期の仕組みも不要です。

型チェック(Phase 2) はコンパイル時間全体の約2/3を占める最重要フェーズです。ファイル間の型参照があるため、単純な並列化はできません。Go版では、複数の型チェッカーインスタンスを作成する方式を採用しています。4コアなら4つのチェッカーが、それぞれファイルのサブセットを担当します。ASTは読み取り専用として共有し、各チェッカーは独立して動作します。

出力(Phase 3) もファイル単位で並行処理が可能です。

goroutineの優位性

JavaScriptのWorker Threadsと、Goのgoroutineを比較すると、その差は歴然です。

項目 JavaScript(Worker Threads) Go(goroutine)
メモリフットプリント 重い(V8インスタンスごと) 軽量(約2KBで開始)
データ共有 SharedArrayBuffer経由で制限的 ネイティブ共有メモリ
生成コスト 高い 極めて低い
スケーラビリティ 数十が実用的な限界 数千〜数万が可能

goroutineは約2KBのメモリで起動できます。V8のWorker Threadとは桁違いの軽量さです。この違いが、コンパイラのような「大量の小さなタスクを同時に処理したい」ユースケースで大きな差を生みます。

メモリ効率の改善

Go版ではメモリの使い方も根本的に変わっています。JavaScriptでは各オブジェクトが個別にメモリ割り当てされますが、Goでは構造体の配列を一括で割り当てできます。

Anders Hejlsbergの分析によると、性能向上の半分はネイティブコンパイルによるもの、残りの半分は共有メモリ並行処理によるものです。つまり、単にGoにしたから速くなったのではなく、Goの特性を活かした並行処理設計との合わせ技で10倍を達成しています。

10倍高速化の内訳 — どこがどれだけ速くなるのか

「10倍速くなる」という数字は印象的ですが、すべての場面で一律10倍になるわけではありません。改善の度合いは、プロジェクトの規模や使い方によって異なります。ここでは具体的なベンチマークを見ていきます。

コマンドラインビルドの改善

2025年3月の初回発表時のベンチマークがこちらです。

コードベース 規模(行数) 現行(TS 5.x) Go版 高速化倍率
VS Code 1,505,000 77.8秒 7.5秒 10.4倍
Playwright 356,000 11.1秒 1.1秒 10.1倍
TypeORM 270,000 17.5秒 1.3秒 13.5倍
date-fns 104,000 6.5秒 0.7秒 9.5倍
tRPC 18,000 5.5秒 0.6秒 9.1倍
rxjs 2,100 1.1秒 0.1秒 11.0倍

注目すべきは、プロジェクト規模が大きいほど高速化の恩恵も大きい傾向がある点です。TypeORMでは13.5倍という数値も出ています。

2025年12月のアップデートでは、TypeScript 6.0との比較データも公開されました。

コードベース TypeScript 6.0 TypeScript 7.0 高速化倍率
Sentry 133.08秒 16.25秒 8.19倍
VS Code 89.11秒 8.74秒 10.2倍
TypeORM 15.80秒 1.06秒 9.88倍
Playwright 9.30秒 1.24秒 7.51倍

TS 6.0はTS 5.xから若干のパフォーマンス変動がありますが、TS 7.0との差は依然として圧倒的です。

エディタ体験の改善

日常的に最も体感できるのは、エディタの応答速度の変化です。VS Codeのコードベースを基準にした測定では、プロジェクトロード時間が9.6秒から1.2秒に短縮されています。8倍の改善です。

大規模プロジェクトで「VS Codeを開いてから型チェックが効き始めるまでの待ち時間」が大幅に短くなります。コード補完、定義ジャンプ、全参照検索、リネーム、ホバーツールチップ、クイックフィックスといった主要な機能はすでに実装済みです。

メモリ使用量の削減

メモリ使用量は現行比で約50%削減されています。一部のワークロードでは最大70%削減との報告もあります。しかもこれは、積極的な最適化をまだ行っていない段階での数値です。

並列型チェック(4チェッカー)使用時は、単一チェッカー比で約20%のメモリ増加がありますが、それでも現行版より大幅に少ないメモリで動作します。

CI/CDパイプラインへのインパクト

ビルド時間の短縮は、CI/CDパイプラインに直接的な影響を与えます。

例えば、VS Code規模のプロジェクトで考えてみます。ビルドが77.8秒から7.5秒になると、PRごとの型チェックが約70秒短縮されます。1日に50件のPRが走るチームなら、1日あたり約58分のCI時間を節約できる計算です。月換算で約29時間。クラウドCIの課金額に換算すると、無視できないコスト削減になります。

高速化されないもの

ここで重要な注意点があります。TypeScriptで書かれたアプリケーション自体の実行速度は変わりません。 高速化はあくまでコンパイル段階(型チェック、トランスパイル)のみです。

コンパイル後に生成されるJavaScriptは同じものですので、ブラウザやNode.jsでのランタイムパフォーマンスには影響しません。「アプリが10倍速くなる」は誤解です。

開発現場への影響 — 今すぐ・近い将来・中長期

TypeScript 7への移行は段階的に進むように設計されています。今日から準備できることもあれば、様子を見るべきこともあります。時間軸に沿って整理していきます。

今すぐ: TypeScript 6.0で準備する

TypeScript 6.0は2026年2月11日にBeta版が公開されました。正式リリースは2026年3月17日の予定です。このバージョンは、現行JavaScriptコードベースに基づく最後のメジャーリリースとして位置づけられています。

TypeScript 6.0の役割は「TypeScript 7への橋渡し」です。以下のデフォルト値が変更されます。

// tsconfig.json — TS 6.0での新デフォルト値
{
  "compilerOptions": {
    "strict": true,          // 旧: false
    "module": "esnext",      // 旧: commonjs
    "target": "es2025",      // 旧: es5
    "types": []              // 旧: 全@types/*パッケージ
  }
}

もし既存プロジェクトがこれらの設定を明示的に指定していない場合、TS 6.0へのアップデートで挙動が変わる可能性があります。今のうちに tsconfig.json で設定を明示しておくのが安全です。

また、TS 7.0で廃止される機能にはTS 6.0で非推奨警告が出ます。主な対象はこちらです。

  • --target es5es2015以上に変更が必要)
  • --moduleResolution nodenodenextまたはbundlerに変更が必要)
  • esModuleInterop: false(常に有効に)
  • import ... asserts構文(withに変更が必要)

非推奨警告は "ignoreDeprecations": "6.0" で一時的に抑制できます。しかし、TS 7.0採用前には対応が必要です。

近い将来: TypeScript 7.0のリリース

TypeScript 7.0のロードマップは以下の通りです。

マイルストーン 時期 内容
Alphaプレビュー 2025年5月 基本的な型チェック
Beta 2025年10月 インクリメンタルビルド・プロジェクトリファレンス
RC 2025年12月 ES2022+ターゲットのJS出力
GA(正式リリース) 2026年(TS 6.0の直後) 全機能対応

今すぐ試したい場合は、以下の方法があります。

# コマンドラインで試す
npm install -D @typescript/native-preview
npx tsgo --project tsconfig.json

# VS Code拡張で試す
# Marketplaceで「TypeScript native preview」を検索してインストール
# 毎日更新されるプレビュー版です

エコシステムへの影響

ツールチェーンへの影響は、そのツールがTypeScript Compiler APIに依存しているかどうかで大きく異なります。

影響が大きいツール(Compiler API依存):

ツール 状況
typescript-eslint Project Service APIの抽象化で対応予定。ただし1-2メジャーバージョンでの完了は困難
ts-morph Compiler APIを直接ラップしており、大幅改修が必要
typia Compiler API依存。対応方針は検討中

影響が小さいツール(独自パーサー使用):

ツール 理由
esbuild 独自のTypeScriptパーサーを使用。型チェック不要
swc Rust製の独自パーサー。型チェック不要
Vite esbuild/Rollupベース。型チェックは別プロセスのtscに委任
tsx esbuildベースで動作

現行のCompiler API(JavaScript API)はTypeScript 7では利用できなくなります。代替として、LSP(Language Server Protocol)ベースのAPI提供や、新しいCorsa APIが検討されていますが、現行APIより機能が制限される可能性があります。

中長期: 開発体験の質的変化

型チェックが10倍速くなることは、単なる「待ち時間の短縮」にとどまりません。

大規模プロジェクトでは、型チェックの遅さが原因で// @ts-ignoreanyを使ってしまうケースがあります。ビルドが高速になれば、こうした妥協の動機が減ります。「型チェックが遅いから省略する」という選択肢がなくなるのです。

また、ツールチェーンの再編も進むと予想されます。OxlintはTypeScript-goをバックエンドとして統合する方向で探索中です。Biome v2(コードネーム"Biotype")は独自の型推論エンジンを導入し、TypeScriptコンパイラに依存しない型対応リンティングを実現しようとしています。

よくある疑問と誤解 — Q&A形式

Q: TypeScriptの文法や型システムは変わりますか?

変わりません。 変わるのはコンパイラの「実装言語」であり、TypeScriptという言語そのものは同じです。テストケース約20,000件中、TypeScript 6.0と7.0で異なるエラー結果を出すのはわずか74件(未実装機能か意図的な変更)。互換性の目標は**99.99%**です。

Q: GoをインストールしないとTypeScriptが使えなくなりますか?

いいえ。 TypeScript 7のコンパイラはネイティブバイナリとして配布されます。npm install でこれまでと同じようにインストールできます。Go言語の開発環境は不要です。

Q: 既存のTypeScriptプラグインやtransformerは動きますか?

Compiler APIに依存しているものは、そのままでは動きません。 新しいCorsa APIへの対応が必要になります。ただし、TypeScript 6.0とTypeScript 7.0は並行してメンテナンスされるため、ツールの対応が進むまでの猶予期間はあります。

Q: セルフホスティングをやめることのデメリットは?

TypeScriptコンパイラへのコントリビューションには、TypeScriptではなくGoの知識が必要になります。コントリビューターの層が変わる可能性はあります。ただし、Anders Hejlsbergは「No single language is perfect for every task(すべてのタスクに完璧な言語はない)」と述べており、実用性を最優先した判断であることを強調しています。

Q: TypeScriptの書き方を変える必要がありますか?

基本的にはありません。 ただし、TypeScript 6.0/7.0でデフォルト値が変更される設定(strict: truemodule: esnext等)への対応は必要です。これはコンパイラ実装の変更とは別の、言語バージョンアップに伴う通常の変更です。

Q: WebAssemblyで動かせますか?

現時点では懸念が残ります。 Vue.js作者のEvan Youは、GoのWASM性能について具体的な懸念を表明しています。esbuildのWASMビルド(Go製)がブラウザ内でJS製バンドラーより遅いことを具体例として指摘しました。ブラウザベースのエディタやプレイグラウンドでの利用には、今後の改善が待たれます。

まとめ — TypeScript 7がもたらす新しい開発体験

この記事の要点を振り返ります。

  • GoはRustより速いから選ばれたのではない。 既存コードベースとの構造的類似性により、確実に「ポート」できることが最大の理由
  • 10倍高速化は、ネイティブコンパイルと並行処理の合わせ技。 VS Codeプロジェクトで77.8秒→7.5秒、エディタ起動は8倍高速化
  • アプリの実行速度は変わらない。 高速化はコンパイル段階のみ
  • TypeScript 6.0が移行の橋渡し。 非推奨警告に今から対応しておくのが得策
  • Compiler API依存ツールは要注意。 typescript-eslint、ts-morph等は対応に時間がかかる見込み

今やるべきこと

  1. TypeScript 6.0 Betaを既存プロジェクトで試し、非推奨警告を確認する
  2. tsconfig.jsonのデフォルト値変更の影響をチェックする
  3. @typescript/native-previewでtsgoの速度を体感してみる

TypeScript 7は、言語そのものを変えるのではなく、言語を支える基盤を刷新するプロジェクトです。開発者が書くコードは変わりません。しかし、そのコードが型チェックされ、ビルドされるスピードは劇的に変わります。

大規模プロジェクトで「ビルド待ち」がなくなる世界。それがTypeScript 7がもたらす新しい開発体験です。


参考リンク:

Discussion