1
2

【JavaScript、TypeScript】未入力チェックで0を入力しているのにfalseになるお話

Last updated at Posted at 2024-09-24

はじめに

JavaScript、TypeScriptにおいて0がfalseとして判定されること自体は知っていましたが、
空文字も含めるといろいろとややこしかったのでまとめてみます。
間違い等あったらご指摘いただけるとありがたいです。

参考にさせていただいた記事

0はfalseと等価である

JavaScript(TypeScript)において0はfalsyな値であると定義されています。
https://developer.mozilla.org/ja/docs/Glossary/Falsy

偽値 (falsy または falsey) な値とは、論理型コンテキストに現れたときに偽とみなされる値です。

そのため以下のような場合はfalseとなります。

if(0)
if("")

これを知らずにif(value)で未入力チェックなどをしていると、入力しているのにエラーが発生するぞ!という状況になってしまいます。
こちらに関しては参考記事を見ていただければと思います。

0は許可するけど空文字ははじきたい場合

汎用的な未入力チェックなどで空文字もはじきたい場合、if(value == null)if(value == undefined)ではfalseとなります。
条件を追加する必要がありますが、この場合は少しややこしくなります。
単純にif(value == null || value == "")にするとまた0がはじかれるようになってしまいます。
空文字""は等価演算子==で比較した場合0と等価になります。

オペランドの型が異なる場合は、比較前に同じ型に変換を試みます。
数値と文字列を比較する場合、文字列を数値に変換しようとします。

そしてNumber("")は0が返却されると定義されています。

空文字列またはホワイトスペースのみの文字列は 0 に変換されます。

具体的な変換プロセス
"" == 0
↓ (空文字列を数値に変換)
Number("") == 0
↓ (Number("")は0を返す)
0 == 0

このことから、等価演算子でははじかれてしまうため厳密等価演算子===を使用する必要があります。

厳密等価演算子 (===) は、二つのオペランドが等しいことを検査し、論理値で結果を返します。等価演算子とは異なり、厳密等価演算子はオペランドの型が異なる場合、常に異なるものと判断します。

サンプルコード

javascript
function test(value){
    return value == null || value ===""
}    

console.log(test(0))
console.log(test(""))
console.log(test(null))
console.log(test(undefined))

結果

false
true
true
true

TypeScriptで気を付けなくてはいけないこと

TypeScriptで厳密等価演算子を使用する場合はJavaScriptとは違い型を正確に推論します。
そのため0 === ""はエラーが発生します。
どうしたらええんやという話ですが、関数を使用して引数として値を渡すと暗黙的にany型となるためエラーが発生しなくなります。

typscript
function test(value){
    return value == null || value === ""
}

console.log(test(0))
console.log(test(""))
console.log(test(null))
console.log(test(undefined))

ただし、anyの使用はできる限り避けたほうが良いです。
型を明示的にした場合は以下のようになります。

typescript
function test(value: unknown): boolean {
  return value == null || value === "";
}

console.log(test(0))
console.log(test(""))
console.log(test(null))
console.log(test(undefined))

もっといいやり方がある場合は教えていただきたいです。

まとめ

0がfalseなだけであると簡単ですが、空文字やTypScriptの型のあたりが入ってくると少しややこしくなるなと思いました(自分も一回ハマりました)
何と何を比較するとtrueになるのか一覧にしておきます。

等価演算子
0 == "":true
0 == null:false
0 == undefined:false
"" == null:false
"" == undefined:false
null == undefined:true
厳密等価演算子
0 === "":false
0 === null:false
0 === undefined:false
"" === null:false
"" === undefined:false
null === undefined:false
1
2
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
1
2