TypeScriptのコンパイル方法:tsc・型チェック・JavaScript出力を解説
TypeScriptのコンパイルをtsconfig.jsonと実行例で解説。型チェック、出力先、noEmit・noEmitOnError、targetとmodule、watchとoutFileの違いを整理します。
TypeScriptのコンパイラは、コードの型を検査し、設定に応じてJavaScriptを出力します。出力されたJavaScriptは、Node.jsやブラウザーなどの実行環境で動きます。型チェックとファイル出力は別の処理で、設定によってはエラーがあっても出力されるため、意図に合った設定が必要です。
この記事では、一つのファイルを指定する方法と、tsconfig.json を使ってプロジェクト全体を扱う方法を確認します。前提はインストール記事の学習用環境です。サンプルはTypeScript 4.9.4で確認しています。
コンパイルの基本手順
コンパイルするコードを用意する
src/main.ts を作成します。
export {};
function add(left: number, right: number): number {
return left + right;
}
const result = add(10, 20);
console.log(result); // 30
型注釈の : number は、変換後のJavaScriptには残りません。数値として使えるかを開発時に検査するための情報です。公式の型の消去に関する説明
ファイル名を指定してコンパイルする
プロジェクトのルートで次を実行します。package.json の type は commonjs とする前提です。
npx tsc src/main.ts --strict --target ES2020 --module NodeNext --outDir dist --noEmitOnError
node dist/main.js
この場合、出力先は dist/main.js です。--target ES2020 は出力するJavaScriptの構文の水準、--module NodeNext はNode.jsに合わせたモジュールの扱いを指定します。
コマンドに入力ファイル名を直接指定すると、tsconfig.json は読み込まれません。設定ファイルがあるプロジェクトでは、次の節の --project を使うと、設定を一か所にまとめられます。公式の設定ファイルの説明
設定ファイルで管理する
プロジェクトのルートに tsconfig.json を作成します。
{
"compilerOptions": {
"target": "ES2020",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"rootDir": "src",
"outDir": "dist",
"strict": true,
"noEmitOnError": true,
"sourceMap": true
},
"include": ["src/**/*.ts"],
"exclude": ["src/**/*.test.ts"]
}
この設定で、src 内のコードを元のディレクトリ構成に沿って dist へ出力します。sourceMap によって、生成されたJavaScriptと元のTypeScriptの対応を示す .js.map も作られます。
npx tsc --project tsconfig.json
node dist/main.js
--project と入力ファイル名の直接指定は併用できません。ファイル群を設定で管理するか、一つのファイルにコマンドラインで設定を渡すかを選びます。
よく使うオプションの役割
target:出力するJavaScriptの構文の水準を指定します。実行環境の対応に合わせます。moduleとmoduleResolution:モジュールの出力・解釈と、読み込み先の解決方法を指定します。outDir:生成物の出力先を指定します。strict:厳密な型チェックの一群を有効にします。noImplicitAnyも含まれます。noImplicitAny:型を推論できず暗黙のanyになる箇所を診断します。正常に型推論できるコードまで、型注釈を必須にする設定ではありません。noEmitOnError:コンパイラのエラーがある場合、新しい生成物を出力しません。noEmit:型チェックなどの検査だけを行い、生成物を出力しません。sourceMap:デバッガーで元のTypeScriptと対応付けるための情報を出力します。
既定値はコンパイラのバージョンや関連オプションによって変わることがあります。出力形式を安定させたい設定は明示しましょう。特に「target の既定値は常に最新」「module は常にCommonJS」という理解は適切ではありません。公式の設定リファレンス
target を下げても、新しい標準APIの実装が自動追加されるわけではありません。例えば実行環境に必要なAPIがない場合は、対応する環境を選ぶか、別途互換性を補う必要があります。
型チェックだけを行う・変更を監視する
次のコマンドは、それぞれ別の用途で実行します。監視コマンドは終了するまで動き続け、停止するときはターミナルで Ctrl+C を押します。
# JavaScriptを出力せず、型チェックする
npx tsc --project tsconfig.json --noEmit
# ファイルの変更を監視してコンパイルする
npx tsc --project tsconfig.json --watch
noEmitOnError を指定しても、前回までに出力したファイルは削除されません。コンパイルに失敗した後で古い dist/main.js を実行し、新しいコードが動いていると思い込まないように、終了結果を確認してください。
対象ファイルと出力形式の注意点
include は入力ファイルを見つけるためのパターンです。exclude はその探索対象を絞りますが、完全な読み込み禁止の仕組みではありません。対象のコードからインポートされたファイルは、exclude に一致していても型チェックの対象に入る場合があります。公式の exclude の説明
outFile は、どのモジュール形式でも使える結合機能ではありません。グローバルなスクリプトや対応するAMD・System形式などに用途が限られ、CommonJSやES Modulesを一般的に一つへまとめる用途には使えません。公式の outFile の説明
Next.jsなどのフレームワークは、変換や出力を独自のビルド処理で行います。この記事の学習用設定をそのまま上書きせず、フレームワークの設定と型チェックの役割を確認してください。
ビルドが成功したかを正しく判断する
出力の有無だけで判断しない
コンパイラの終了コードと診断を確認します。エラー時に新しい出力を止めても、以前のdistが残っている場合があります。古い出力を実行して成功したと判断しないよう、ビルド手順と成果物を対応させます。
型チェックを自動化する
変更を取り込む前にtsc --noEmitを実行する手順を用意すると、手元で確認し忘れた型エラーに気づけます。コンパイルとは別に、計算結果や外部データの扱いを確かめるテストも実行します。