若くない何かの悩み

何かをdisっているときは、たいていツンデレですので大目に見てやってください。

TypeScript の Promise<T> が Promise<T, E> ではない理由の心当たり

TypeScript の Promise の型 だと、型パラメータが Promise#then 側しかなくて、 Promise#catch 側の型が any になってしまって不便だ。 もし、catch 側の型についても型引数で指定できたなら、より安全なプログラミングができる。

そこで、catch 側の型を指定していない理由について考察してみた。

理想

const promise: IdealPromise<T, E> = getPromise();

promise
  .then((x) => { /* x は T 型 */ });

promise
  .catch((e) => { /* e は E 型 */ });

実際

const promise: Promise<T> = getPromise();

promise
  .then((x) => { /* x は T 型 */ });

promise
  .catch((e) => { /* e は any 型 */ });

考察

前提条件

TypeScript/JavaScript には以下の制約がある:

  • 制約1: TypeScript は関数の評価時に発生しうる例外の型を検査しない
  • 制約2: JavaScript はなんでも throw できる(例: throw null
  • 制約3: new Promise(fn) に与えられた関数 fn が例外 e を発生させた時、この Promise インスタンスは理由 e で棄却状態になる

帰結

これらの制約の上でうまく型付けしようとすると、catch 側は any にならざるをえない。

TypeScript の型検査器は、new Promise(fn)fn が発生しうる例外の型を推定する材料を持っていない。 JavaScript はどんな値・オブジェクトも例外として発生させられるので、fn から発生しうる例外の型は any であると推論するほかない。 そして、この fn が例外 e を発生させたとき、この Promise は e で棄却状態になる。 このとき、e の型は、前述の通り any としか推論できない。したがって、catch の引数の型は常に any である。 であれば、catch 側の型引数は必要ない。

理想に近づくためには

TypeScript に例外の型宣言ができるようになれば、できそうな気がする?

例えば:

function resolver<T, E>(resolve: (x: T) => void, reject: (e: E) => void): a throws E {
  // ...
}

const promise: Promise<T, E> = new Promise(resolver);

promise
  .then((x) => { /* x は T 型 */ });

promise
  .catch((e) => { /* e は E 型 */ });

SEE ALSO

github.com github.com github.com

JavaScript開発における多段式エラープルーフについて

第14回HTML5ビギナーズで、JavaScriptデバッグ作業を短くする「多段式エラープルーフ」について発表してきました。

スライド

speakerdeck.com

コードのサンプル

github.com

まとめ

JavaScriptデバッグ作業を素早くこなすなら、多段式エラープルーフが必要です。

師弟登壇2015で発表してきました

発表スライド

会場からは、「内定時代の課題は必須なのか?」という質問をいただきました。 これについては、「内定時の課題は、この時期研究で忙しいからダメですが通用するので、セルフコントロール可能です」という回答です。 実際、会社側が無理言ってる感が強いので、研究忙しくてダメでした、は許容されてました。

感想

懇親会

カヤックさんとはてなさんとディレクター不遇話を話してました。ディレクターの研修が雑問題とか、リスペクトされづらい問題とか、なぜか責任とらされる問題とか。後ろ2つの問題はともかく、ディレクター研修雑問題は、師弟登壇20XX ディレクター編などて改善していきたいという気持ちですね。