結論
個人的なコーディングルールとしては 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があるかもしれない」と考えながら実装することを考えると
コストは十分回収できていると感じている。