TypeScriptでの開発において、コードを変更するたびに手動でコンパイルを実行するのは非常に非効率です。

この課題を解決し、ソースコードの変更をリアルタイムで検知して自動的にビルドを行う仕組みが、TypeScriptコンパイラに標準搭載されている--watch(または-w)オプションです。

開発効率を劇的に向上させるためには、単にこのオプションを有効にするだけでなく、プロジェクトの規模や開発環境に合わせて適切な設定と運用ルールを適用することが重要です。

本記事では、2026年現在の最新のベストプラクティスに基づき、tsc --watchを使いこなすための高度な設定方法から、パフォーマンスを最大化する運用のコツまで詳しく解説します。

tsc –watchの基本動作と導入メリット

tsc --watchは、TypeScriptコンパイラを「監視モード」で起動するためのオプションです。

通常、tscコマンドを実行すると、プロジェクト内のファイルを一通りコンパイルして終了しますが、監視モードではプロセスが終了せずに待機状態となります。

基本的な実行方法

最もシンプルな実行方法は、ターミナルで以下のコマンドを入力することです。

TypeScript
// カレントディレクトリのtsconfig.jsonに従って監視を開始する
tsc --watch

// 省略形での実行
tsc -w

実行すると、ターミナルには以下のようなメッセージが表示されます。

text
[12:00:00 PM] Starting compilation in watch mode...

[12:00:05 PM] Found 0 errors. Watching for file changes.

この状態でソースファイルを編集して保存すると、ファイルの変更を検知して差分のみが再コンパイルされます。

これにより、開発者はコンパイルコマンドを意識することなく、コーディングに集中できるようになります。

導入による具体的なメリット

tsc --watchを導入することで得られる主なメリットは以下の通りです。

  1. フィードバックループの高速化:型エラーを保存直後に確認できるため、バグの早期発見につながります。
  2. コンパイル時間の短縮:後述する増分ビルド機能と組み合わせることで、変更があった箇所だけを処理するため、プロジェクト全体を再ビルドするよりも圧倒的に高速です。
  3. ツールの連携:エディタのバックグラウンドプロセスとして動作させることで、常に最新のビルド結果を保つことができます。

パフォーマンスを最大化するtsconfig.jsonの設定

大規模なプロジェクトになると、ファイルの監視対象が増えることでCPUリソースを過剰に消費したり、コンパイル速度が低下したりすることがあります。

これらを防ぎ、快適な監視環境を構築するためにはtsconfig.jsonの最適化が欠かせません。

増分ビルド(incremental)の有効化

--watchを使用する際に最も重要な設定がincrementalです。

これを有効にすると、TypeScriptは前回のコンパイル情報を.tsbuildinfoというファイルに保存し、次回のコンパイル時に変更がない部分の解析をスキップします。

JSON
{
  "compilerOptions": {
    "incremental": true,
    "tsbuildinfoFile": "./.tsbuildinfo",
    "outDir": "./dist"
  }
}

この設定により、監視モードでの再開時や、一度プロセスを終了した後の再起動時の速度が大幅に向上します。

watchOptionsによる詳細な監視制御

TypeScript 3.8以降、tsconfig.jsonにはwatchOptionsというセクションが追加されており、ファイルの監視方法を細かく制御できます。

OSのファイルシステムイベントの挙動が不安定な場合や、ネットワークドライブ経由で開発している場合に特に有効です。

オプション名設定値の例説明
watchFileuseFsEvents個別ファイルの監視方法を指定します。
watchDirectoryuseFsEventsディレクトリ全体の監視方法を指定します。
fallbackPollingdynamicPriorityPollingOSのイベントが利用できない場合のポーリング戦略。
excludeDirectories["**/node_modules"]監視対象から除外するディレクトリを指定します。

以下は、パフォーマンスを重視したwatchOptionsの設定例です。

JSON
{
  "watchOptions": {
    "watchFile": "useFsEvents",
    "watchDirectory": "useFsEvents",
    "fallbackPolling": "dynamicPriority",
    "synchronousWatchDirectory": false,
    "excludeDirectories": ["**/node_modules", "dist"]
  }
}

node_modulesやビルド出力先ディレクトリを明示的に除外することで、不要な監視コストを削減し、CPUの負荷を抑えることができます。

開発フローにおける運用のコツ

tsc --watchは単独で使うだけでなく、他のツールやワークフローと組み合わせることで真価を発揮します。

ここでは、プロフェッショナルな現場でよく用いられる運用のテクニックを紹介します。

型チェック専用としての運用(–noEmit)

近年、Viteやesbuildといった非常に高速なビルドツールが登場しています。

これらのツールは型チェックをスキップしてトランスパイルのみを行うため、実行速度は速いですが型安全性が担保されません。

そこで、「ビルドはVite、型チェックはtsc –watch」という役割分担が一般的になっています。

この場合、TypeScript側ではファイルを出力する必要がないため、--noEmitフラグを併用します。

TypeScript
// 型チェックのみを継続的に実行する
tsc --watch --noEmit

この運用により、コードを書きながらリアルタイムでターミナル上の型エラーを確認しつつ、ブラウザ上の動作確認は高速なビルドツールに任せるという、ストレスのない開発環境が構築できます。

プロジェクト参照(Project References)との組み合わせ

モノレポ構成や大規模プロジェクトでは、プロジェクトを複数の小さな単位に分割する「プロジェクト参照」機能を利用することがあります。

この場合、単なる--watchではなく、ビルドモードの--build-b)と組み合わせる必要があります。

TypeScript
// 依存関係のあるプロジェクトを含めて監視・ビルドする
tsc -b --watch

これにより、ライブラリ側のコードを変更した際に、それを参照しているアプリケーション側のコードも依存関係を正しく解釈して再ビルドされるようになります。

ターミナル出力の見やすさを向上させる

監視モードで開発していると、エラーメッセージが流れてしまい、最新の状態が分かりにくくなることがあります。

これを防ぐために、--prettyオプションや、外部ツールを利用して画面をクリアする方法があります。

TypeScriptの標準機能では、以下のコマンドでエラーを色付きで読みやすく表示できます。

TypeScript
tsc --watch --pretty

また、エラーが発生したときだけ通知を送るユーティリティツール(tsc-watchなど)を利用すると、コンパイル成功時に特定のスクリプト(サーバーの再起動など)を実行させるといった高度な自動化も可能になります。

よくあるトラブルと解決策

tsc --watchを使用している際、稀にファイルの変更が検知されなかったり、CPU使用率が異常に高くなったりすることがあります。

ファイル変更が検知されない場合

特にLinux環境などで、監視できるファイル数の上限(inotifyの上限)に達している場合に発生しやすい問題です。

この場合は、OS側の設定を変更するか、前述のwatchOptionsfallbackPollingを試してください。

また、エディタの「セーブ時にフォーマット」機能が動作している場合、ファイルが一時的に削除・作成される挙動となり、監視が外れてしまうことがあります。

この場合は、ディレクトリの監視設定をuseFsEventsに固定することで改善する場合があります。

CPU負荷が高い場合の対処法

監視対象が広すぎる可能性があります。

tsconfig.jsonのinclude設定を見直し、ソースコードが存在するディレクトリ(srcなど)のみを指定しているか確認してください。

JSON
{
  "include": ["src/**/*"],
  "exclude": ["node_modules", "**/*.spec.ts"]
}

デフォルトではディレクトリ内の多くのファイルがスキャン対象となるため、範囲を絞り込むことはパフォーマンス改善に直結します。

実践的な設定例:フルスペックのtsconfig.json

これまでに解説した内容を統合した、開発効率とパフォーマンスを両立するためのtsconfig.jsonの例を以下に示します。

JSON
{
  "compilerOptions": {
    "target": "ESNext",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "incremental": true,               // 増分ビルドを有効化
    "tsbuildinfoFile": "./.tsbuildinfo", // ビルド情報を保存
    "noEmit": true,                    // 型チェック専用にする場合はtrue
    "esModuleInterop": true,
    "skipLibCheck": true               // 型定義ファイルのチェックをスキップして高速化
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist", "coverage"],
  "watchOptions": {
    "watchFile": "useFsEvents",
    "watchDirectory": "useFsEvents",
    "fallbackPolling": "dynamicPriority",
    "excludeDirectories": ["**/node_modules", "dist"]
  }
}

この設定ファイルをベースに、プロジェクト固有の要件(バックエンドならNode.js向けの設定、フロントエンドならJSXの設定など)を追加していくのがスムーズです。

まとめ

tsc --watchは、TypeScript開発における生産性の要となる強力な機能です。

ただコマンドを叩くだけでも十分に便利ですが、「増分ビルド(incremental)の活用」「watchOptionsによる監視の最適化」「–noEmitによる型チェックの分離」といったテクニックを組み合わせることで、その真価を引き出すことができます。

特に近年のモダンなフロントエンド開発では、ビルドツールとtscを併用するスタイルが定着しています。

本記事で紹介した設定や運用のコツを参考に、自身のプロジェクトに最適な監視環境を構築してみてください。

小さな設定の積み重ねが、日々の開発における快適さとスピードを大きく左右することになるでしょう。