null or undefined どっちを使うべき?
TypeScript(JavaScript)のお話です。
背景: VuexをTypeScriptで開発したときにハマった罠
VuexをTypeScriptで書きたくてvuex-module-decoratorsを使っているのだが、vuex-module-decoratorでstateをundefinedにすると変更が検知されない罠があった。
要点だけまとめると、undefinedではなくnullで初期化すれば回避できたわけだが、
これまでnullもundefinedもあまり違いを意識してこなかったので、これを機会にまとめてみることにした。
nullとundefinedの違い
公式ドキュメントでは?
TypeScriptの公式ガイドブックにはこう書いてあった。
https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#null-and-undefined
nullandundefinedJavaScript has two primitive values used to signal absent or uninitialized value:
nullandundefined
absent or uninitializedってことは「値がないまたは初期化されていない」ということだとして、その状態を表す値としてnullとundefinedの2つがある、ってことを言っている。
でもnullとundefinedの違いについては書かれていない。
コーディング規約では?
世の中にある有名なコーディング規約ではこれらをどう定義しているんだろう。と思い、ググったらすぐヒットするTypeScript Deep Diveにこう書いてあるのを見つけた。
nullvsundefined
- 明示的に使用不可能にするために、どちらも使用しないことを推奨します。
理由:これらの値は、値間の一貫した構造を維持するためによく使用されます。TypeScriptでは型を使用して構造を表します
- 一般的に
undefinedを使用してください(代わりに{valid:boolean,value?:Foo}のようなオブジェクトを返すことを検討してください)- APIまたは従来のAPIの一部である場合は
nullを使用します理由:Node.jsの慣例通りです。NodeBackスタイルコールバックのerrorはnullです。
nullとundefinedJavaScript(と、TypeScript)は、
nullとundefinedという2つのボトム型(bottom type)があります。これらは異なる意味を持っています。
- 初期化されていない:
undefined。- 現在利用できない:
null。
なるほど、まとめると
-
undefinedは初期化されていない状態を、nullは現在使えない状態を表す値 -
nullもundefinedも使うな - どうしても使いたいなら
undefinedを使え - ただしAPIなどは
nullを使え
こんなところだろうか。
ちなみに、他にも色々検索してみたが、基本的にTypeScriptではnullよりundefinedが好まれる傾向があるように感じた。
-
https://qiita.com/kabosu3d/items/06ce9266bc2db1226421
- undefinedやnullを書くことが必要なときは、できる限りundefinedを使うこと。 [SHOULD]
- 理由: 一貫性のため。
-
https://github.com/microsoft/TypeScript/wiki/Coding-guidelines
- Use undefined. Do not use null.
まとめ
- TypeScript的には
undefinedとnullで迷ったらundefinedを使うのがなんとなく多数派っぽい。 - でも、Vuexみたいに
undefinedで初期化したらうまく動かないライブラリも世の中にはある。 - 今後、もしTypeScriptのライブラリを提供することがあったら、
nullとundefinedは混在せず、どちらかを統一したものを提供したい。