『tsc が遅い』はチームの大問題
大規模 TypeScript プロジェクトでは tsc の遅さがチーム生産性に直結します。本記事では編集部の視点で、パフォーマンス改善手法を公開情報をもとに整理します。tsconfig 厳格設定 もご参考に。
遅くなる原因
(1) 型推論の複雑性:Conditional Types。(2) 巨大な依存型:node_modules 込み。(3) 循環参照。(4) declarationを毎回生成。(5) 未使用 import 多数。
incremental ビルド
(1) incremental: true:変更差分のみ。(2) tsBuildInfoFile:キャッシュ場所。(3) composite: true:project references 連携。(4) watch modeと組合せ。(5) 10〜100倍高速化(公開情報をもとに)。
Project References
(1) monorepo で威力。(2) サブプロジェクト個別ビルド。(3) tsconfig.json の references。(4) tsc --buildでビルド。(5) 型解決の高速化。Monorepo 設計 もご参考に。
skipLibCheck の活用
(1) node_modules の型チェック省略。(2) 大幅高速化。(3) 欠点:依存ライブラリの型エラー検知できず。(4) CI で full checkに分割。(5) デフォルト false の選択。
SWC / esbuild の利用
(1) SWC:Rust 製・tsc の数倍速。(2) esbuild:Go 製・最速級。(3) 型チェックは別タスク:tsc を分離。(4) Vite/Next.js が標準採用。(5) CI: SWC で transpile + tsc で型のみチェック。Vite ビルドチューニング もご参考に。
型のシンプル化
(1) 過度な Conditional Types 回避。(2) any/unknown の使い分け。(3) 型エイリアスより interface(一部のケース)。(4) importでなくtype-only import。(5) verbatimModuleSyntax有効化。
計測ツール
(1) tsc --extendedDiagnostics。(2) tsc --generateTrace:詳細プロファイル。(3) typescript-analyze。(4) VSCode の TS Server logs。(5) CI 時間モニタリング。
失敗しがちなパターン
(1) incremental 無効化。(2) node_modules 重複型定義。(3) Conditional Types 5段ネスト:tsc 暴走。(4) 巨大 union types。(5) declaration 毎回生成。対策は、(1)incremental 常時 on、(2)pnpm/resolutions、(3)型分割、(4)Branded Types、(5)CI のみ generate、です。