TL;DR
--lib es6
のように lib
オプションを指定し, core-js のような polyfill を利用する.
バージョン
$ tsc --version
Version 3.2.2
きっかけ
TypeScript + Vue.js に入門しようと思って公式ドキュメントを読み, だいたい概要をつかめたところで quick start guides
をやってみた.
すると, "!" マークを enthusiasm
個連続して結合した文字列を返すという部分でこんなコードが書かれているではないか:
get exclamationMarks(): string {
return Array(this.enthusiasm + 1).join('!');
}
この部分は ES6 で追加された String.prototype.repeat()
メソッドによって, 以下のようにもっと簡単に書けるはずである:
get exclamationMarks(): string {
return "!".repeat(this.enthusiasm);
}
早速手元で書きかえて試してみると, 次のようなエラーが出た:
TS2339: Property 'repeat' does not exist on type '"!"'.
あれ, おかしいな... と思って調べてみると, こんな issue があった.
I think you're confusing transpilation with auto-polyfilling. TypeScript doesn't automatically polyfill for you like Babel does, but does perform syntactic downleveling (e.g. for arrow functions).
If you want to use ES6 runtime prototype methods, I'd simply include an appropriate ES6 polyfill and its accompanying definition file.
確かにこの時点では筆者も TypeScript のコンパイラはトランスパイルと polyfill を同時に行ってくれるものだと思い込んでしまっていた.
しかし実際のところ TypeScript が行うのは, 例えば arrow functions のような ES6 の 構文 を ES5 に変換することであって, Babel のような polyfill (ES6 で追加されたメソッドやオブジェクトを ES5 の仕様でエミュレートするコードを挿入すること) は行わない (と筆者は理解した). なので core-js のような polyfill 集と, その型宣言ファイルを導入する必要があるということになる. 1
--lib
オプション
TypeScript 2.0 からは --lib
オプションを指定することでビルトインの型宣言を利用できるようになっていたようだ. 2
したがって --lib es6
のように指定すれば, あとはただコード内で polyfill を import
などすれば良い.
まだ良く理解できていないけど, --lib es2018
とすれば String.prototype.repeat()
も使えるし, ES7 で追加された Array.prototype.includes()
も使える. es2018
を指定すれば自動的に ES5 から ES2018 までの全ての型宣言ファイルが読み込まれるということなのかな.
注意事項とお願い
筆者は TypeScript や JavaScript には全然詳しくないので, 内容に誤りが含まれる可能性があります.
もし何かあればコメントでご指摘いただけると嬉しいです.