LoginSignup
2
0
記事投稿キャンペーン 「2024年!初アウトプットをしよう」

TypeScript strict-boolean-expressionsのエラーとその解消方法について

Last updated at Posted at 2024-01-14

はじめに

最近、新規プロジェクトに配属されました。
if文を使って、値がundefinedの場合の条件式を今まで通り、!を使って書いたところ、ESLintのエラーが発生しました。初めて見るエラーだったので、内容と解決方法について詳しく調べてみました。

  • 言語:TypeScript
  • ライブラリ:React

先にこの記事で伝えたいことをまとめておきます。

  • strict-boolean-expressionsエラーは、boolean型の値が必要な場所で、それ以外の型が指定された場合に発生する
  • 等価演算子を使うとnull == undefined // => trueと判定される
  • x == nullと書いた場合、xがnullundefinedの場合という条件を表すことができる

問題

startTimeDate | undefinrd型をとるstateです。
startTime===undefinedの場合は早期リターンしたかったので、条件分岐を!を使って以下のように書きました。

const [startTime, setStartTime] = useState<Date | undefined>()

if (!startTime) {
  return 
}

すると!startTimeに以下のようなESLintのエラーが発生しました。

hooks_ts_—_narekan-web.png

そして保存すると、勝手に以下のように変換され、エラーが解消されました。

if (startTime == null) {
  return 
}

一連の流れでいくつかの疑問が浮かんだので、調べました。

疑問点

  • このエラーの意味は何か
  • なぜこれまでのプロジェクトではこのエラーが発生しなかったのか
  • なぜstartTime == nullでエラーが解消されるのか
  • ソースコードにはどのように書くか

このエラーの意味は何か

Unexpected nullable object value in conditional. An explicit null check is required.

今回発生しているESLintのエラーはTypeScript strict-boolean-expressionsです。

公式ドキュメントによると、このエラーは、boolean型の値が必要な場所で、それ以外の型が指定された場合に発生します。

例えば以下の時、エラーが発生します。numがundefined型をとる可能性があるからです。

// nullable numbers are considered unsafe by default
let num: number | undefined = 0;
if (num) {
  console.log('num is defined');
}

以下のように修正することでエラーは解消されます。

// nullable values should be checked explicitly against null or undefined
let num: number | undefined = 0;
if (num != undefined) {
  console.log('num is defined');
}

今回発生したエラーのように、条件式に!startTimeと書いてしまうと、startTimeがfalsyのときtrueと判定されます。つまり、本当はundefinedのときだけtrueと判定したいのに、startTimeが0や空文字の場合にもtrueと判定されてしまうということです。

このような曖昧な評価を防ぐためにstrict-boolean-expressionsは必要ということですね!

なぜこれまでのプロジェクトではこのエラーが発生しなかったのか

以前のプロジェクトを確認したところ、ESLintの設定でstrict-boolean-expressionsがOFFになっていました。

なぜstartTime == nullでエラーが解消されるのか

まずは使用されている文法について考えます。

等価演算子==

等価演算子では、型が異なっていても同じと見なすことがあります。
厳密には、値の型が異なる場合型の変換ができないか試みてから値が等しいかを比較します。

// 等価演算子の場合
console.log(null == undefined); // => true
console.log(0 == "0"); // => true

// 厳密等価演算子の場合 
console.log(null === undefined); // => false
console.log(0 === "0"); // => false

nullとundefindが等しいというのは感覚と反していて気持ち悪いと思いました😕
厳密等価演算子はよく使いますが、等価演算子は実務で初めて使いました。実際、今回と同じ使い方以外ではあまり使わないみたいですね。

よって、今回のようにstartTime == nullと書いた場合、startTimeがnullundefinedの場合という条件を表すことができます。
厳密等価演算子を使って表すと、startTime === null || startTime === undefindという条件になるので、前者の方が簡潔でいいですね。

// 等価演算子の場合
if (startTime == null) {
  return 
}
// 厳密等価演算子の場合
if (startTime === null || startTime === undefind) {
  return 
}

ソースコードにはどのように書くか

先輩とも相談して、今回はstartTimeがundefindの場合という条件が、より正確に示せた方がわかりやすいだろうと判断して、以下のように修正することにしました。

簡潔に書くことと、伝わりやすいかのどちらを優先するのかは、チームによっても考え方が異なりそうですね。

const [startTime, setStartTime] = useState<Date | undefined>()

if (startTime === undefined) {
  return 
}

まとめ

  • strict-boolean-expressionsエラーは、boolean型の値が必要な場所で、それ以外の型が指定された場合に発生する
  • 等価演算子を使うとnull == undefined // => trueと判定される
  • x == nullと書いた場合、xがnullundefinedの場合という条件を表すことができる

終わりに

プロジェクトによって設定ルールが異なるため、ソースコードの書き方が異なることを学びました。
strict-boolean-expressionsがONの時は、より厳密に判定条件を書く必要があるので注意していこうと思います!
また、null==undefined =>trueとなることも学びました。なかなか納得しにくいですが覚えておきます!

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0