結論
個人的なコーディングルールとしては undefinedに統一することにしている。
理由
- nullとundefinedを使い分けない理由
- 実務で違いを明確にして使い分けたい場面がほぼない(後述のUnionで事足りている)
- この区別の認識を、チーム内に浸透させるのは難しい(認識合わせのコストとリターンが見合わない)
- undefinedに寄せる理由
-
undefinedは言語仕様上自然発生してしまうが、nullは意図的な発生になるため
-
区別して使いたい人へ
区別して使いたいこだわりがある人に対しては、
「それUnionで表現できませんか?」と提案しておく。
例えば、何かUIで設定するような場合、「未設定/未選択」のようなパターンを
「未設定は、明示的に値を設定していないということだからnull」などとやってはないだろうか?
おそらく、それは値がないことを一つの状態として表現したUnion型が適している可能性がある。
■nullを使って未設定を表現する
type gender = "male" | "female";
let selectedGender: gender | null = null;
selectedGender = "male"; ■未設定の状態を定義する
type gender = "male" | "female" | "unset"; // 未設定をunsetとして使う
let selectedGender: gender = "unset";
selectedGender = "male"; 補足
稀に nullが発生するケースとして、外部APIから受け取ったレスポンスに nullが含まれる
ということがある。
筆者はこのような場合は
レスポンスマッピング〜実際にコード内で使うまでの間に、null合体演算子 ??を用いて undefinedに変換して使うようにしている。
const value = input ?? undefined; 多少面倒ではあるが、その後の使い分けや「nullがあるかもしれない」と考えながら実装することを考えると
コストは十分回収できていると感じている。