TypeScriptでアプリケーションを開発する際、最初に直面する重要な設定項目の一つが tsconfig.json における target です。
このプロパティは、記述したTypeScriptコードをどのバージョンのJavaScriptとして出力するかを決定する、いわばプロジェクトの「出力基準」を定める役割を担っています。
2026年現在、JavaScriptの進化はさらに加速しており、環境に応じた適切な設定を選択することは、アプリケーションの実行速度やファイルサイズ、さらには開発体験を最適化するために不可欠な工程となっています。
本記事では、プロジェクトの要件に基づいた最適なJavaScriptバージョンの選定手法について、具体例を交えながら詳しく検討していきます。
targetオプションの役割とコンパイルの仕組み
TypeScriptの target オプションは、コンパイラに対して「どの世代のJavaScript構文を使用してコードを出力すべきか」を指示するためのものです。
TypeScriptは、最新の言語仕様(ECMAScript)で記述されたコードを、古いブラウザや特定のNode.js環境でも動作するように変換する「ダウンレベルコンパイル(Downleveling)」を行う機能を備えています。
例えば、最新の構文であるアロー関数やクラス、非同期処理(async/await)を記述した場合、target の設定によって出力結果は大きく異なります。
ターゲットによるコード変換の差異
具体的に、アロー関数を含むTypeScriptコードがどのように変換されるかを見てみましょう。
// 元のTypeScriptコード
const greet = (name: string): string => {
return `Hello, ${name}!`;
};
このコードを target: "ES5" でコンパイルした場合、以下のようなJavaScriptが出力されます。
// target: "ES5" の出力結果
var greet = function (name) {
return "Hello, ".concat(name, "!");
};
一方で、target: "ES2015"(ES6)以降を指定した場合、アロー関数はそのまま保持されます。
// target: "ES2015" 以降の出力結果
const greet = (name) => {
return `Hello, ${name}!`;
};
このように、target は 古い環境への互換性を維持するために、最新の構文を古い構文へと書き換える範囲 を制御します。
設定を古くすればするほど、多くの環境で動作するようになりますが、同時により冗長なコードが出力されるという側面も持っています。
実行環境ごとの最適なターゲット設定
プロジェクトに最適な target を選ぶには、まず「そのコードがどこで実行されるか」を明確にする必要があります。
2026年の主要な実行環境を前提とした、一般的な推奨設定を整理します。
ブラウザ向けフロントエンド開発
現在のWebブラウザ(Chrome, Edge, Safari, Firefox)は、いわゆる「エバーグリーンブラウザ」として自動更新が一般的になっており、最新のECMAScript仕様の多くをネイティブでサポートしています。
- モダンブラウザのみを対象とする場合:
ES2022以降、あるいはESNextを検討します。これにより、クラスフィールドやトップレベルAwaitなどの最新機能を変換コストなしで利用でき、ランタイムのパフォーマンスを最大限に引き出せます。 - 広範な互換性が必要な場合:
依然として古いモバイルブラウザや特定の企業内環境をサポートする必要があるなら、ES2018やES2020あたりが現実的な妥協点となります。 - レガシー環境(IE等)の完全排除:
2026年において、ES5への変換が必要なケースは極めて限定的です。特別な理由がない限り、ES2015(ES6)未満をターゲットにするメリットはありません。
Node.jsによるサーバーサイド開発
Node.js環境では、実行するNode.jsのバージョンによってサポートされている構文が明確に決まっています。
| Node.jsバージョン | 推奨されるtarget設定 |
|---|---|
| Node.js 20.x (LTS) | ES2022 |
| Node.js 22.x (LTS) | ES2023 |
| Node.js 24.x (LTS) | ESNext |
サーバーサイドではブラウザのような「ユーザー環境のばらつき」を考慮する必要がないため、実行環境のNode.jsがネイティブでサポートしている最高バージョンに合わせるのが最も効率的です。
これにより、コンパイル後のデバッグが容易になり、スタックトレースも読みやすくなります。
2026年における標準的な選択肢と「ESNext」
TypeScriptの設定において ESNext というキーワードをよく目にしますが、これには注意が必要です。
ESNextの正体とリスク
ESNext は、TypeScriptコンパイラがサポートしている最新のJavaScript仕様を指します。
これは「動的なターゲット」であり、TypeScriptのバージョンが上がるたびに指し示す内容が変化します。
- メリット:常に最新のJavaScript機能をフル活用したコードを出力できる。
- デメリット:TypeScriptをアップデートした際に、出力されるコードの構文が変わり、予期せぬ実行環境エラーを引き起こす可能性がある。
ライブラリ開発などの、利用側の環境が限定できないプロジェクトでは、ESNext ではなく ES2022 のようにバージョンを固定して指定することが推奨されます。
一方で、Viteなどの高速なビルドツールを併用しているフロントエンド開発では、TypeScript側では ESNext を出力し、最終的なブラウザ互換性の調整は後続のトランスパイラ(esbuildやSWCなど)に任せるという構成が一般的です。
パフォーマンスとコードサイズへの影響
target の選択は、単に「動くかどうか」だけでなく、アプリケーションの品質にも直結します。
コードの肥大化(Payload Size)
古いバージョン(ES5など)をターゲットにすると、最新の構文を模倣するために大量のヘルパー関数が生成されます。
// async/awaitを使用した関数
async function fetchData() {
const response = await fetch('/api/data');
return response.json();
}
これを ES5 でコンパイルすると、__awaiter や __generator といった複雑なステートマシンがコード内に埋め込まれます。
これにより、JavaScriptのファイルサイズが劇的に増加し、初期ロード時間に悪影響を及ぼします。2026年のモダンな環境においては、ネイティブの async / await をそのまま出力させることで、転送量を削減し、ブラウザの最適化機能を活用するのが正解です。
実行速度の最適化
モダンなブラウザのJavaScriptエンジン(V8など)は、ネイティブの最新構文に対して高度な最適化を行います。
例えば、クラス構文やプロミスは、ポリフィルや変換後のコードよりも、ネイティブ実装の方が高速に動作するケースが多くなっています。
したがって、実行環境が許す限りtargetを新しく保つことは、パフォーマンスの向上に直接寄与します。
targetとlibおよびmoduleの密接な関係
target を設定する際に、併せて理解しておくべきなのが lib と module オプションです。
lib設定との連動
target を指定すると、TypeScriptはデフォルトでそのバージョンに対応した型定義(lib)を自動的に読み込みます。
target: "ES5"の場合:PromiseやMapの型定義は含まれません。target: "ES2020"の場合:PromiseやBigInt、String.prototype.matchAllなどの型定義が標準で有効になります。
もし古い target を使いつつ、最新のAPIを利用したい場合は、手動で lib プロパティを調整する必要があります。
しかし、型定義があることと、実行環境にその実体(ポリフィル)があることは別問題である点に注意してください。
module設定との切り分け
よく混同されますが、target は「個々の構文(関数や変数)」の変換を制御し、module は「ファイル間のインポート・エクスポート(import/export)」の形式を制御します。
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler"
}
}
現代的なWeb開発では、target を ES2022 程度にしてモダンな構文を維持しつつ、module を ESNext または NodeNext に設定してTree Shaking(不要コードの削除)を有効にするのがベストプラクティスです。
トラブルシューティングと注意点
target 設定を変更した際に遭遇しやすい問題についても触れておきます。
クラスフィールドの挙動変化
target を ES2022 以降に設定すると、クラスのプロパティ初期化の挙動が変わることがあります。
具体的には useDefineForClassFields オプションがデフォルトで true になります。
class User {
name = "Guest";
}
これが Object.defineProperty を使った定義になるか、単なる代入になるかは target に依存します。
特に MobXやTypeORMなどのデコレータを多用するライブラリを使用している場合、この挙動の変化によってランタイムエラーが発生することがあるため、設定変更時には十分なテストが必要です。
ポリフィルの必要性
target を新しくしても、古い環境で動作させたい場合は、構文の変換(Transpilation)だけでなく機能の補填(Polyfill)が必要です。
target はあくまで構文を書き換えるだけであり、Array.prototype.flat() や Object.fromEntries() といったメソッドそのものを追加してくれるわけではありません。
これらは core-js などの外部ライブラリを用いて補う必要があります。
まとめ
TypeScriptの target 設定は、単なるバージョンの選択ではなく、互換性・パフォーマンス・開発効率のバランスを決定する戦略的なパラメータです。
2026年における選定指針をまとめると以下のようになります。
- Webアプリ開発:原則として
ES2022以上を選択。Vite等のビルドツールを併用する場合は、TypeScript側はESNextでも良い。 - Node.js開発:利用しているNode.jsのLTSバージョンがサポートする最高バージョン(例:Node.js 22なら
ES2023)に合わせる。 - ライブラリ開発:利用者の環境を考慮し、やや保守的に
ES2020前後を選択するのが安全。
プロジェクトの初期段階で適切な target を設定することは、将来的な技術負債を回避し、最新のJavaScriptエコシステムの恩恵を享受するための第一歩です。
実行環境のシェア率やサポート期間を定期的に見直し、必要に応じてターゲットを引き上げていく習慣をつけましょう。
