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
null
andundefined
JavaScript has two primitive values used to signal absent or uninitialized value:
null
andundefined
absent or uninitialized
ってことは「値がないまたは初期化されていない」ということだとして、その状態を表す値としてnull
とundefined
の2つがある、ってことを言っている。
でもnull
とundefined
の違いについては書かれていない。
コーディング規約では?
世の中にある有名なコーディング規約ではこれらをどう定義しているんだろう。と思い、ググったらすぐヒットするTypeScript Deep Diveにこう書いてあるのを見つけた。
null
vsundefined
- 明示的に使用不可能にするために、どちらも使用しないことを推奨します。
理由:これらの値は、値間の一貫した構造を維持するためによく使用されます。TypeScriptでは型を使用して構造を表します
- 一般的に
undefined
を使用してください(代わりに{valid:boolean,value?:Foo}
のようなオブジェクトを返すことを検討してください)- APIまたは従来のAPIの一部である場合は
null
を使用します理由:Node.jsの慣例通りです。NodeBackスタイルコールバックのerrorはnullです。
null
とundefined
JavaScript(と、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
は混在せず、どちらかを統一したものを提供したい。