eslint: strict-boolean-expressions がデフォルトで一番厳しい設定ではない
最も厳密なスタイルでの記述を求めるのであれば、以下
code:.eslint.js
{
rules: {
'@typescript-eslint/strict-boolean-expressions': [
'error',
{ allowString: false, allowNumber: false, allowNullableObject: false }
],
}
}
個人的な結論としては、numberのみ厳密にした。
code:.eslint.js
{
rules: {
}
}
---
ここからは細かい話
このルールのデフォルトのオプションは以下
code:ts
const defaultOptions: Options = [
{
allowString: true,
allowNumber: true,
allowNullableObject: true,
allowNullableBoolean: false,
allowNullableString: false,
allowNullableNumber: false,
allowAny: false,
allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing: false,
},
];
おそらく使い勝手のためにいくつかのオプションはtrueになっている
そのため例えば以下の例でエラーにならない
code:ts
declare const a: 0 | 1 | null
if (a) {
....
}
この場合、0はfalsyなので、nullだけを弾きたい場合には a !== null と書くべきだが、それを強制しないようにしてある。
ここで、allowNumber: false にしてあげると上記はエラーになり明示的な記述を求められるようになる。うれしい。
しかし、このオプションは次も明示的な記述を強制することになる。
code:ts
declare const a: 1 | null
if (a) { // also error! must use a !== null
...
}
この場合には個人的には明示的に書かなくても良いと思っている。意図に反しやすい傾向にあるケースである "数字だけを取りたくて0を取り逃してしまうケース" を明示的に記述させることでバグに気づかせるというのがベストな強制具合だと思う。
ただ、現状ではそのような設定はできない。ちなみに関連するissueはいくつかある。
個人的な結論としてはliteral typeとして 0 を入れやすい傾向にあるので、allowNumberのみ厳密化してfalseにした。たとえばタプルのインデックスとして取り回したりするためである。
そのほかについては型文字 "" などはliteral typeとして記述するケースが少ないため、記述のしやすさを優先して厳密化しないことにした。オブジェクトについても同様である。
使い勝手としてはいちいちnullとの明示的な比較を求められるのはいささか面倒に感じることもあるかもしれない。場合によっては0をfalsyな集合とするほうが文化にあっているケースもあるだろう。
なかなかどちらかスタンダードであるべきかと考えると文化に依る部分で難しい。
eslintのスタンスとしては、もともとのjsでの文化でよくある記述をよりスタンダードであるとして捉えて、そこまで厳密にせず書きやすさを優先するような塩梅を選んでいるのだろう。