tsgo 使ってみた

AIくんに試行錯誤の記録記事を書いてもらった

emoji: "🚀"
type: "tech"
topics: ["typescript", "tsgo", "vite", "electron", "performance"]
published: true
title: "TypeScript Native Preview (tsgo) 導入で3.4倍高速化を実現した話 - Vite設定ファイルエラーとの戦い"はじめに
2025年5月23日、Microsoft TypeScriptチームから新しいGo言語実装コンパイラ「TypeScript Native Preview」(通称tsgo
)が公開されました。公式発表では「最大10倍の高速化」を謳っており、大規模なElectron + Reactプロジェクトを個人開発している私も導入を検討することにしました。
この記事では、実際のプロジェクトにtsgo
を導入した際の試行錯誤、遭遇した問題、そして最終的な解決方法について詳しく記録します。
対象プロジェクト
- ElectronベースのVRChat写真管理アプリ
- 技術スタック: Electron + React + TypeScript + Vite
- 規模: TypeScript約20,500行、ファイル数約170個
tsgoとは
tsgo
は将来的にTypeScript 7で標準となる予定の新しいコンパイラで、以下の特徴があります:
- Go言語で実装 - ネイティブコンパイルによる高速化
- 並行処理 - 共有メモリ並列処理の活用
-
既存コードとの互換性 - 既存の
tsc
と同じインターフェース
導入手順
1. パッケージのインストール
yarn add -D @typescript/native-preview
2. バージョン確認
npx tsgo -v
# Version 7.0.0-dev.20250523.1
パフォーマンス比較結果
全体の型チェック時間
まず現在のtsc
での型チェック時間を測定:
time yarn lint:type-check:tsc # tscベース
# 結果: 6.738秒
次にtsgo
での型チェック時間:
time yarn lint:type-check:tsgo # tsgoベース
# 結果: 1.994秒
結果: 3.4倍の高速化を実現!
詳細メトリクス比較
メインプロジェクト
メトリクス | tsc | tsgo | 改善率 |
---|---|---|---|
Total time | 3.85s | 0.765s | 5.0倍高速化 |
Check time | 2.15s | 0.591s | 3.6倍高速化 |
Memory used | 504MB | 533MB | -5.8% |
Electronプロジェクト
メトリクス | tsc | tsgo | 改善率 |
---|---|---|---|
Total time | 1.68s | 0.253s | 6.6倍高速化 |
Check time | 0.82s | 0.116s | 7.1倍高速化 |
Memory used | 285MB | 234MB | 18%削減 |
公式の「10倍高速化」には及ばないものの、実用的なパフォーマンス向上を確認できました。
最初の壁: Vite設定ファイルエラー
順調に見えた導入でしたが、tsgo
で型チェックを実行すると以下のエラーが発生:
electron/vite.config.ts:3:10 - error TS2305: Module '"...../node_modules/vite/index"' has no exported member 'defineConfig'.
3 import { defineConfig } from 'vite';
~~~~~~~~~~~~
一方、従来のtsc
では同じコードが正常に動作しています。
試行錯誤1: 型インポートの削除
最初の対策として、Viteの型インポートを削除してプレーンなオブジェクトで設定を定義しました:
// 修正前(エラーになる)
import type { ConfigEnv, UserConfig } from 'vite';
export default ({ command }: ConfigEnv): UserConfig => { ... }
// 修正後(動作するが型安全性を犠牲)
export default ({ command }: { command: string }) => { ... }
これでtsgo
は動作しましたが、型安全性を犠牲にするという課題が残りました。
根本原因の発見
調査を進める中で、GitHub Issues #518という重要な情報を発見しました。
tsgoの既知の制限事項
この問題はtsgo
の既知の制限事項で、複雑なESM exportsフィールドを持つライブラリの型解決に問題があることが判明:
-
tsgo
はnode_modules/vite/index
を参照しようとする - 実際の型定義は
node_modules/vite/dist/node/index
にある - ESMの複雑な型解決エンジンがまだ完全ではない
試行錯誤2: patch-packageの検討
GitHubのIssueでは、Viteのpackage.json
を直接修正する方法が提案されていました:
"exports": {
".": {
"import": "./dist/node/index.js",
"types": "./dist/node/index.d.ts", // ← この行を追加
"require": "./index.cjs"
}
}
patch-package
を使ってこの修正を適用することも検討しましたが:
-
node_modules
の変更が必要 - チームメンバーとの共有が複雑
- Viteのバージョンアップ時の影響
これらの理由で断念しました。
最終解決: exclude方式
最終的に採用したのは、Vite設定ファイルをtsgo
の型チェック対象から除外する方法でした。
設定変更
// tsconfig.json
{
"exclude": [
"node_modules",
"**/*.spec.ts",
"**/*.spec.tsx",
"**/*.test.ts",
"**/*.test.tsx",
"vite.config.ts", // 追加
"electron/vite.config.ts" // 追加
]
}
// electron/tsconfig.json
{
"exclude": ["node_modules", "**/*.spec.*", "**/*.test.*", "vite.config.ts"]
}
Vite設定ファイルを元の形式に復元
// 型安全性を復活
import { defineConfig } from 'vite';
import type { ConfigEnv, UserConfig } from 'vite';
export default ({ command }: ConfigEnv): UserConfig => {
// 型安全な設定
};
最終的なワークフロー
package.jsonの設定
{
"scripts": {
// 標準(tsgo使用)- 日常開発用
"lint": "biome check . && lint:type-check",
"lint:type-check": "lint:type-check:tsgo",
// 完全チェック(tsc使用)- Vite設定含む
"lint:type-check:tsc": "tsc --noEmit && tsc --noEmit -p electron",
// tsgo専用
"lint:type-check:tsgo": "tsgo --noEmit && tsgo --noEmit -p electron"
}
}
型チェック戦略
コマンド | 実行時間 | 対象 | 用途 |
---|---|---|---|
yarn lint (tsgo) |
1.994秒 | Vite設定以外 | 日常開発 - 高速 |
yarn lint:type-check:tsc |
6.738秒 | 全ファイル | 完全チェック |
メリット・デメリット
メリット ✅
- 高速化: 3.4倍の型チェック高速化
- 型安全性: Vite設定ファイルの型安全性を維持
-
シンプル:
node_modules
の変更不要 - 保守性: Viteのバージョンアップの影響なし
デメリット ⚠️
-
設定分離: Vite設定ファイルは別途
tsc
でチェック必要 - プレビュー版: 他のライブラリでも同様の問題が発生する可能性
学び・今後の展望
tsgoの現状
- パフォーマンス: 確実に高速化を実現
- 互換性: ESM複雑な型解決に一部制限あり
- 実用性: 適切な回避策で実用可能
プロジェクトへの影響
個人開発では以下の効果を実感:
- 開発サイクル短縮: 型チェック待ち時間の大幅削減
- 生産性向上: 3.4倍高速化により、よりアジャイルな開発が可能
- メモリ効率: 特にElectronプロジェクトで21%のメモリ削減
まとめ
tsgo
の導入は一筋縄ではいかない部分もありましたが、最終的に以下を実現できました:
- 3.4倍の型チェック高速化
- 型安全性の完全維持
- 実用的な開発ワークフロー
TypeScript 7でtsgo
が標準になることを考えると、今回の経験は貴重な先行投資となりました。ESMライブラリとの互換性問題は今後改善されることが期待されますが、現時点でも適切な回避策により実用レベルで活用できることが分かりました。