In short: ES2017 が動く環境を対象にビルドするなら
例として ES2017 が動く環境を対象にビルドを考える。
- tsconfig の target に es2017 を指定
- tsconfig の lib に es2017 を指定
- dom も必要であれば加える
- 他の機能、例えば Array.prototype.flat が欲しくなったら、手動で polyfill を追加した後に tsconfig の lib に
es2019.arrayを加える
- eslint-plugin-compat を導入する
- サポート対象のブラウザ環境で Web API が使えるかどうかを確認するために使う
- polyfill の入れ忘れ防止になる
こうすれば、ES2017 より後に追加されたシンタックスはトランスパイルされるので安心して使える。もし ES2017 より後に追加された標準組み込みオブジェクトやメソッドを使っていたらコンパイルが落ちるし、各種 Web API は eslint-plugin-compat が弾いてくれる。だいぶ盤石なはず。
前提: ECMAScript に含まれるもの、含まれないもの
TypeScriptはlibに含まれないものが使われていたらコンパイルエラーを出す。では、まず ECMAScript がどこまで含んでいるかを整理しよう。
ECMAScript が含むもの
- 標準組み込みオブジェクト(Promise や Math、String など)
- 各種シンタックス (オプショナルチェーン演算子
?.など) - オブジェクトのメソッド(Array.prototype.flat など)
ECMAScript が含まないもの
- Web API (WindowインターフェイスやDOM API、IntersectionObserver など)
- DOM API は WHATWG が定める DOM Living Standard で規定されている
- IntersectionObserver は W3C が定めている
- History API は HTML Living Standard が定めている
TypeScript のコンパイル時の役割
TypeScript はコンパイル時に大まかに2つの役割を果たす。
- シンタックスのトランスパイル (オプショナルチェーン演算子(
?.)など) - ECMAScript に入っている標準組み込みオブジェクトやメソッドが target、lib のバージョン内にない場合にコンパイルを失敗させる
TypeScript は polyfill を入れたりはしないが、target、lib のバージョン内にない標準組み込みオブジェクトがを使っていたらコンパイルを通さない。この場合、手動で polyfill を入れて動くようにした後に lib へ該当するものを追加してコンパイルを通るようにする。
上記の通り、TypeScript は基本的に Web API について関知しない。例えば lib: ["dom"] を指定すると、target のバージョンに関わらず IntersectionObserver が扱えてしまう。これ以上はどうしようもないので eslint-plugin-compat で対処する。