TypeScript

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.jsontypecommonjs とする前提です。

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の構文の水準を指定します。実行環境の対応に合わせます。
  • modulemoduleResolution:モジュールの出力・解釈と、読み込み先の解決方法を指定します。
  • 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を実行する手順を用意すると、手元で確認し忘れた型エラーに気づけます。コンパイルとは別に、計算結果や外部データの扱いを確かめるテストも実行します。

関連記事

TypeScriptとは・学習順・目的別の記事一覧へ戻る

y.
WRITTEN BY

y_ymo10

SEの部屋で、JavaScript・TypeScript・React.js・Next.jsの開発ノートを公開しています。

ほかの開発ノートを読む →