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: Function
と true
の比較になり compile できない。
一方で if (x === true) ...
などという記述は一般的な言語で避けられているであろう boolean との明示的な比較であり、冗長な記述だ。そこで、すこし迷っている。
truthy / falsy のある言語での true / false はそれぞれの代表的な値でしかない。それらの明示的な比較は基本的には避けるべきだ。悩ましい。
理想を言えば x ? ... : ...
や if (x) ...
の x
に boolean 以外を認めない option があると良いのだけど、現状はなさそうだ。ちなみに Microsoft/TypeScript#9041 やその元 Issue で提案はされている。
lint で対応する手もあるだろう。個人的に tslint は遅いので避けたいのだけど……。