まず結論

トランスパイルとは、ある種類のソースコードを、別の近い種類のソースコードへ変換することです。
Web開発では、TypeScriptをJavaScriptへ変換したり、JSXをJavaScriptへ変換したりする場面でよく出てきます。
const count: number = 1;
TypeScriptはブラウザがそのまま実行する言語ではありません。実行前にJavaScriptへ変換されます。
const count = 1;
このような変換を、広い意味でトランスパイルと呼びます。
コンパイルとの違い
コンパイルは、ソースコードを別の形式へ変換する大きな概念です。C言語を機械語へ変換するようなものもコンパイルです。
トランスパイルは、その中でも「比較的近い言語同士の変換」を指す言葉として使われます。
| 用語 | 例 | イメージ |
|---|---|---|
| コンパイル | C -> 機械語 | 実行形式へ変換 |
| トランスパイル | TypeScript -> JavaScript | 近い言語へ変換 |
| ビルド | 変換、結合、最適化全体 | 公開用にまとめる |
ただし実務では、厳密に分けず「TypeScriptをコンパイルする」と言うこともあります。言葉よりも、何が何に変換されているかを理解することが大切です。
TypeScriptで何が消えるか
TypeScriptの型は、開発中にミスを見つけるための情報です。ブラウザで実行されるJavaScriptには基本的に残りません。
function greet(name: string): string {
return `Hello, ${name}`;
}
変換後は、型注釈が消えます。
function greet(name) {
return `Hello, ${name}`;
}
つまり、TypeScriptは本番のブラウザ上で型チェックしているわけではありません。型チェックは、ビルド前や開発中に行います。
JSXで何が起きるか
Reactなどで使うJSXも、ブラウザがそのまま理解する構文ではありません。
const element = <button>保存</button>;
ビルド時にJavaScriptの関数呼び出しへ変換されます。実際の形は設定やランタイムによって変わりますが、考え方としては「見た目がHTMLに近い構文をJavaScriptへ変換している」と理解すれば十分です。
新しいJavaScriptを古い環境向けに変換する
トランスパイルは、TypeScriptだけではありません。新しいJavaScript構文を、古いブラウザでも動きやすい形へ変換することがあります。
例:
- optional chaining
- nullish coalescing
- class fields
- async/await
どこまで古い環境へ対応するかは、プロジェクトの設定や対象ブラウザによります。
変換しても守れないこと
トランスパイルは万能ではありません。
- 実行時のAPIが存在しない問題
- サーバとブラウザの違い
- データ形式の不一致
- セキュリティ上の設計ミス
たとえば、構文は変換できても、古いブラウザに fetch が存在しなければ別の対策が必要になります。
注意: トランスパイルは「構文を変える」ことが中心です。実行環境にAPIがあるかどうかは別問題です。
入力と出力を追えば用語に迷わない
TypeScriptコンパイラは型検査を行い、型注釈を除いたJavaScriptを出力できます。Babelは構文変換の規則に従い、新しいJavaScriptやJSXを別のJavaScriptへ変換します。どちらも広い意味ではコンパイル工程ですが、「トランスパイル」は似た抽象度の言語間変換を強調する言葉です。名称より、何を入力し、何を検査し、どの環境で実行できる何を出力するかを確認します。
| 工程 | 入力 | 主な出力・結果 | 保証しないこと |
|---|---|---|---|
| TypeScript型検査 | TS/TSX | 型エラー | 実行時データの正しさ |
| TypeScript emit | TS/TSX | JavaScript | 必要なAPIの存在 |
| JSX変換 | JSX/TSX | 関数呼び出しを含むJS | DOM描画の成功 |
| 構文変換 | 新しいJS | 対象向けJS構文 | 未提供APIの実装 |
| minify | JavaScript | 小さいJavaScript | 古い環境との互換性 |
| bundle | 複数モジュール | 配信用ファイル群 | 型安全性 |
型が消えた後に起こること
user.age as numberは実行時の値を数値へ変換しません。APIが文字列を返しても、型アサーションは生成JavaScriptから消えます。外部入力は実行時バリデーションで確認します。同様に、targetを古い構文へ下げても、実行環境にfetchやPromiseがなければ動きません。必要ならpolyfillを選び、対象ブラウザと配信量への影響を確認します。
よくある誤解
「TypeScriptが通れば実行時エラーはない」は誤りです。型検査は通信失敗や不正JSONを防ぎません。「Babelがあれば古いブラウザで必ず動く」も誤りで、構文とAPIは別です。「コンパイルとトランスパイルは完全に排他的な正式分類」でもありません。ツールの文書がcompilerと呼ぶこともあり、会話では工程の入出力を明示する方が正確です。用語の勝敗より、失われる情報と残る実行時責任を共有します。
動作確認:生成物と対象環境を確認する
小さなTSXファイルをビルドし、型注釈、optional chaining、JSXが生成物でどう変わるか読みます。型エラー時にemitされる設定か、対象ブラウザで構文エラーが出ないか、必要なAPIが存在するかを確認します。ブラウザ対応はローカルの新しい環境だけで判定しません。
CIでは型検査とビルドを別コマンドとして失敗させ、生成物を実際のランタイムで起動します。外部入力に誤った型を与えるテストも追加します。変換成功、型検査成功、実行成功は別の結果なので、それぞれに確認方法が必要です。
まとめ
トランスパイルは、TypeScriptやJSX、新しいJavaScript構文を、実行できるJavaScriptへ変換する工程です。
ビルドの中には、トランスパイル、バンドル、最小化など複数の処理が含まれます。エラーを読む時は、「型チェックで落ちたのか」「変換で落ちたのか」「実行時に落ちたのか」を分けて考えると原因を追いやすくなります。