等価演算子(==)と厳密等価演算子(===)とは
JavaScriptでもそうですが、基本的にTypeScriptでも
等価演算子(以下、==)ではなく、厳密等価演算子(以下、===)を用いることが推奨されています。
というのも==と===は厳密には違う挙動をします。
等価演算子 (==) は、二つのオペランドが等しいことを検査し、論理値で結果を返します。厳密等価演算子とは異なり、オペランドの型が異なる場合には型の変換を試みてから比較を行います。
厳密等価演算子 (===) は、二つのオペランドが等しいことを検査し、論理値で結果を返します。等価演算子とは異なり、厳密等価演算子はオペランドの型が異なる場合、常に異なるものと判断します。
実際に試してみます。
数値型の比較。
const a: number = 1;
const b: number = 1;
// 両方ともtrue
console.log(a == b);
console.log(a === b);
文字列型でも同じです。
const a: string = "hoge";
const b: string = "hoge";
// 両方ともtrue
console.log(a == b);
console.log(a === b);
数値型と文字列型の比較は、
TypeScriptではコンパイル(トランスパイル)時に以下のように怒られます。
※コンパイル自体は通るので注意。
const a: number = 1;
const b: string = "1";
// JavaScriptではtrue
console.log(a == b);
// JavaScriptではfalse
console.log(a === b);
error TS2367: This condition will always return 'false' since the types 'number' and 'string' have no overlap.
なので以下のようなfalsyな値の比較にも用いることが出来ません。
const a: string = "";
const b: number = 0;
// JavaScriptではtrue
console.log(a == b);
// JavaScriptではfalse
console.log(a === b);
error TS2367: This condition will always return 'false' since the types 'string' and 'number' have no overlap.
==は二つのオペランドの型が異なる場合、暗黙の型変換が行われ、それ同士を比較してtrueとなることがあります。
===は二つのオペランドの型が異なる場合、常にfalseになるのでより厳密な一致判定が行えるということですね。
==を使えそうな場面を考えてみる
オブジェクト型を比較した場合(構造の等価性)
const a = { id: 1, name: "hoge"};
const b = { id: 1, name: "hoge"};
const a2 = a;
// どちらもfalse
console.log(a == b);
console.log(a === b);
// どちらもtrue
console.log(a == a2);
console.log(a === a2);
残念ながら、==と===でも別々に作られたオブジェクトはfalseになるようです。
==/===は、2つのオブジェクトの構造を比較したい場合は、使えません。
ではbool値ではどうでしょうか。
const a: boolean = null;
const b: undefined = undefined;
console.log(a == b); // true
console.log(a === b); // false
nullとundefinedを比較した場合、==ならtrue、
===ならfalseを返します。
さらにnullとundefinedの比較はコンパイル時にも怒られず、
使えそうです。
しかし、以下のように書けば同じことが出来そうです。
const a: boolean = null;
const b: undefined = undefined;
// どちらもtrue
console.log(a === null || a === undefined);
console.log(b === null || b === undefined);
この場合、若干コードが短く書けるぐらいなので、
基本的には===を使用した方が良さそうです。
まとめ
公式で推奨されていた通り、型まで等価であることが確認できる===を使うのが良さそうです。
これに限ったことではないですが、なにがどう推奨されているのかという理由を理解出来れば、ただ良いとされているからなんとなく使うということも無くなるかと思います。(自分への戒め)
少しでも参考になれば幸いです。
参考
追記(2022/5/26)
falsyな値とは、falseとみなされる値のことです。