【実務・中級編】 targetプロパティとECMAScriptバージョンの関係 – TypeScript実践ガイド

TypeScriptの `target` 設定:その「妥協点」があなたのアプリの命運を握っている

現場でコードを書いていると、つい「とりあえず `ESNext` にしておけば最新機能が使えて最高じゃん」と思いがちだよね。でも、ちょっと待ってほしい。その甘い判断が、数ヶ月後に「特定の古い環境でだけ謎のクラッシュをする」という、悪夢のようなデバッグ地獄を招くことになる。

今回は、TypeScriptの心臓部の一つである `tsconfig.json` の `target` プロパティについて、ただの文法解説ではなく、「ブラウザの裏側で何が起きているのか」という視点から、現場のリアルな勘所を叩き込んでいくよ。

—

1. `target` とは一体何者なのか?

`target` は、TypeScriptがコンパイルされた結果、「どの時代のJavaScript構文(ECMAScriptバージョン)として出力するか」を定義する設定だ。

例えば、`async/await`。これは比較的新しい構文だけど、これを `target: “ES5″` でビルドすると、TypeScriptは「あぁ、この環境には `async` なんて気の利いたものはないんだな」と判断し、巨大なジェネレータ関数やステートマシンに変換してくれる。

これが何を意味するか? コードが肥大化するということだ。

現場の判断基準:どこまで「過去」を背負うか

  • ES5: IE11対応が必要な「死の淵」にいる現場用。ほぼ全てのコードが変換され、ビルドサイズは膨れ上がる。
  • ES2015 (ES6): モダンブラウザの最低ライン。`const/let` やアロー関数はそのまま出力される。現代のフロントエンド開発の標準的な出発点だ。
  • ESNext: 最新の機能を使う。ただし、出力先ブラウザが対応していない場合、実行時に即死する。

2. ポリフィル(Polyfill)との境界線を見極める

ここが一番の落とし穴だ。`target` を変えても、「新しいAPI」が使えるようになるわけではない、という点に注意してほしい。

  • 構文の変換 (Transpilation): `target` が担う。(`async/await`, `class` など)
  • APIの補完 (Polyfill): `core-js` などが担う。(`Promise`, `Array.prototype.includes`, `Map`, `Set` など)

つまり、`target: “ES2015″` に設定しても、ブラウザ側に `Array.prototype.includes` が実装されていなければ、`includes` を使った瞬間に `TypeError: … is not a function` でアプリは落ちる。「構文が通ること」と「APIが存在すること」は別問題だということを、心に深く刻んでおこう。

—

3. 実務で「これだけは守れ」という推奨設定

最近の現場で、僕がよく採用する `tsconfig.json` の構成案を置いておく。`target` を極端に下げず、`lib` プロパティで必要なAPIの型定義だけを拾うのが、今のフロントエンド開発の最適解だ。

{
“compilerOptions”: {
// モダンブラウザをターゲットにするのが現代の鉄則
“target”: “ES2020”,

// 実行環境で使えるAPIの型定義を指定
// 構文はES2020、DOMの操作も必要、という構成
“lib”: [“ES2020”, “DOM”, “DOM.Iterable”],

// これをtrueにすると、targetが古くても最新の構文を保とうとする(便利!)
“useDefineForClassFields”: true,

// モジュール解決のルール
“module”: “ESNext”,
“moduleResolution”: “node”
}
}

—

4. 賢いエンジニアの「検証」テクニック

最後に、自分が書いているコードが「どの構文に変換されているか」を瞬時に確認する方法を紹介する。

TypeScript公式の [TypeScript Playground](https://www.typescriptlang.org/play) を使おう。
1. 左上の `TS Config` をクリック。
2. `Target` を `ES5` や `ESNext` に切り替える。
3. 自分の書いたコードが、右側のJavaScriptペインでどう変貌するかを見る。

例えば、`??`(Null合体演算子)を `target: “ES5″` でビルドすると、驚くほど長い三項演算子の羅列に変換されるはずだ。これを見ると、「あ、自分のコードの重さはここで決まるんだな」という感覚が養われるはず。

まとめ:アーキテクトからのアドバイス

`target` 設定は、単なるテキストの書き換え設定ではない。「あなたのプロダクトが、どの時代のユーザーを切り捨てるか」という宣言だ。

  • 無闇に古い `target` を指定しない: バンドルサイズとパフォーマンスが悪化する。
  • `lib` を適切に管理する: 実行環境に存在しないAPIを型定義から除外することで、コンパイル時にエラーを検知できる。
  • BabelやSWCとの連携を考える: 最近はTypeScript単体で変換せず、`target: “ESNext”` にして、変換の最終処理をBabelに任せるのがプロの現場のトレンドだ。

技術は常に動いている。今日設定した `ES2020` も、2年後には古臭いものになっているかもしれない。だからこそ、設定の裏にある「なぜ?」を理解し続けることが、一歩先を行くエンジニアへの近道だよ。

何か詰まったら、いつでも聞いてくれ。現場からは以上だ。

コメント

タイトルとURLをコピーしました