blog.bouzuya.net

2016-08-24 TypeScript で truthy / falsy をさける

bouzuya/bbn-cycle でつまらない bug を埋め込んだ。その code を簡素化して書くと次のようなものだ。

const x = (): string => 'foo';
const y = (): number => {
  // const { x } = { x: false }; // 入れるはずだった行
  return x ? 123 : 456;
};

y: () => number は常に 123 を返してしまう。本来は変数 x: boolean から判断して適切な number を返したい。しかし x: () => string を参照してしまうため、x は常に truthy であり、常に 123 を返す。

TypeScript では truthy / falsy を避けて true / false を使えば、この bug を避けられる。

具体的には return x ? 123 : 456;return x === true ? 123 : 456; とすれば、この bug に気づくことができる。TypeScript で x === true と書けば x: Functiontrue の比較になり compile できない。

一方で if (x === true) ... などという記述は一般的な言語で避けられているであろう boolean との明示的な比較であり、冗長な記述だ。そこで、すこし迷っている。

truthy / falsy のある言語での true / false はそれぞれの代表的な値でしかない。それらの明示的な比較は基本的には避けるべきだ。悩ましい。

理想を言えば x ? ... : ...if (x) ...x に boolean 以外を認めない option があると良いのだけど、現状はなさそうだ。ちなみに Microsoft/TypeScript#9041 やその元 Issue で提案はされている。

lint で対応する手もあるだろう。個人的に tslint は遅いので避けたいのだけど……。