TypeScriptの知識は最初に出た0.8系で止まっているので、噂に聞いてたジェネリクスを試してみる。(ジェネリクス自体は0.9系からある)
型の表現力を試すときは、自分はいつもmap関数の型表現を定義してみることにしている。
function map<A,B>(list: A[], func: (a:A) => B): B[] { return list.map(func); } var strList: String[] = map<Number, String>([1,2,3], x => x.toString()) var strList2 = map([1,2,3], x => x.toString()) //型を省略しても引数から推論してくれる
このmap関数の表現ができる言語とできない言語がある。たとえばC++はだいぶめんどくさいことしないとできなかった。
template<class T, class F> auto map(const std::vector<T> & vec, F fun) -> std::vector<decltype(fun(vec[0]))> { std::vector<decltype(fun(vec[0]))> ret; std::transform (vec.begin(), vec.end(), std::back_inserter(ret), fun); return ret; }
(これは1年ぐらい前に@krustfに教えてもらったやつ。C++14だともっと簡単になるかもしれない。)
Goはテンプレートを持たないので無名のインターフェースとかでごまかしつつやることになる。そもそも速度重視で型表現が豊富な言語じゃねーよ、ってのはググってるとたくさん見つかったので、そういうことなんだと思う。
とにかく、TypeScriptの標準のlib.d.tsじゃどうなってるんだろう、と Array
map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[];
だいたい予想通り。細かい挙動は @yaakaito の人のブログとか @vvakame さんのqiitaとか読めばわかる。
async, awaitはv1.1に
昔見た時はv1.0にはC#のasync相当のものを入れると聞いてたんだけど、さっきロードマップを見ると 1.1になってた。 そもそも ES6ジェネレーターを待つか、自前で定義するか難しいところなので、悩みどころなんだと思う。jsxはyield互換のコードを自力で生成してて辛そうだった。
TypeScriptのプロジェクト上の辛いところは、一応MSのプロダクトなので建前上IEで動かない機能つけるのどうなんだろうな、って展開になりがちな気がする。他にasm.jsとか…。