2016-03-11 に bouzuya/rally-rxjs へ適用した TypeScript -> Babel の多段構成の回避方法を書く。具体的には、型定義として ES2015 (ES6) を使いながら target を es5 にすることで回避した。当該 commit は bouzuya/rally-rxjs#47ff4ca6d5c673e14275f3fa5bf7579d08b71465 。
2016-03-14 に書いたとおり、ぼくは typescript & babel 構成で苦労していた。
こうなった理由は TypeScript にある。
- TypeScript の compiler option を target: es5 にすると、
Promise
の型定義が見つからず compile できない - TypeScript の compiler option を target: es2015 にすると、polyfill を追加してくれなくなり、実行時に Error を投げる
回避策は次の通り。
- target: es5 で型定義を補う
- target: es2015 で polyfill を追加する
実際には 2. を選択し、 TypeScript & Babel の多段構成を採っていた。TypeScript は型を処理し ES2015 を出力する。Babel は ES2015 を処理し ES5 を出力する。
ここで 1. を選択しなかったのは npm package ごとに Promise の型定義が一貫していないこと、わざわざ Promise の型定義を入れたくないことが理由だ。外部 npm package の型定義の調達はとにかく面倒だ。しばしば any
でお茶をにごしている。特に型定義間の依存関係は最悪だ。「もう any
でいいんじゃないか」と思ってしまう。
結果として TypeScript & Babel の多段構成で力任せにやっていた。
これを TypeScript マンのわかめさんが解決してくれた。具体的には 2016-03-14 に書いたやり取りの流れで @vvakame に教えてもらった方法が良かった。
@bouzuya 僕こうやってますね https://t.co/GWS9EvwtUx 型定義だけ --target es6 相当を参照してコンパイル自体は --target es5 で行う感じで
— わかめ@TypeScriptカッコガチ (@vvakame) March 8, 2016
試してみたところ問題なく動く。
この方法が TypeScript & Babel の多段構成と比べて何が良いのか。例えば次のとおりだ。
- babel への依存関係を package.json から削除できる
- babel の transpile にかかる実行時間を削減できる
- babel の install (npm install) の実行時間を減らせる
- 2016-03-14 のような TypeScript & Babel の非互換な部分への配慮をなくせる
どう見ても標準的な方法には見えないのだけど……。そう思い、たずねてみた。
@vvakame これって tsc のオプションで別々に指定できるようになる予定とかってないんですかね?書く分は es6 、出力される分は es5 みたいな……。
— bouzuya (@bouzuya) March 8, 2016
@bouzuya 一応 2.0 でやる気はあるっぽいですよ https://t.co/qzsonKN6P2 https://t.co/Asxfo09zgX
— わかめ@TypeScriptカッコガチ (@vvakame) March 8, 2016
参照する lib の指定は TypeScript 2.0 で検討されているようだ。
追記: 2016-06-20 で逆に TypeScript -> Babel の多段構成を取っている。そちらも参照。