[TypeScript] 型にハテナ(?)をつけるのって、undefinedを指定するのと何か違うの?[オプショナルプロパティ]
こんにちは😊 kesojiです。
最近弊社では丸一日かけて、Vue3/TypeScriptの内製研修を実施しました。
Vue3/TypeScriptにおける便利さや、初学者がつまずきがちな内容について学習しました。
今日はそんなTypeScriptにおけるnull
、undefined
と、この?
について話します。
type Hoge = {
fuga?: string //←このハテナ
}
ちなみに、この ?
をつけたものは「オプショナルプロパティ」と呼ばれます。 ?
自体は「オプショナルプロパティマーカー」って言うみたいです。たぶん。。(ググラビリティが低いですよねこれ。そういうのはChatGPTに聞くとよいです。「TypeScriptの型定義の?ってなんていうの?」。)
論より証拠
とりあえず動かしながら確認してみましょう! TypeScript Playground に実際のコードがありますので、是非こちらで実際のTypeScriptエラーも確認しながら見て頂くと理解が深まるとおもいます。
少々無理矢理な部分がありますが、以下の型のバリエーションを考えてみます。
type stringのみ = {
data: string
}
type stringとundefined = {
data: string|undefined
}
type stringとnull = {
data: string|null
}
type stringとundefinedとnull = {
data: string|undefined|null
}
type ハテナつきstringのみ = {
data?: string
}
type ハテナつきstringとundefined = {
data?: string|undefined
}
type ハテナつきstringとnull = {
data?: string|null
}
type ハテナつきstringとundefinedとnull = {
data?: string|undefined|null
}
これらを受け取る関数を定義します。読みにくいですが、全て同じパターンです。
function stringのみ(a: stringのみ){}
function stringとundefined(a: stringとundefined){}
function stringとnull(a: stringとnull){}
function stringとundefinedとnull(a: stringとundefinedとnull){}
function ハテナつきstringのみ(a: ハテナつきstringのみ){}
function ハテナつきstringとundefined(a: ハテナつきstringとundefined){}
function ハテナつきstringとnull(a: ハテナつきstringとnull){}
function ハテナつきstringとundefinedとnull(a: ハテナつきstringとundefinedとnull){}
そして、ここから実際に関数を呼び出して型エラーが出るか、挙動を確認していきましょう。
文字列を入れてみる
文字列を入れてみます。これはもちろん全部問題無く入りますね。
nullを入れてみる
nullを入れてみます。nullを許容していない型でエラー(赤下線)が出ました。
undefinedを入れてみる
undefinedを入れてみます。ハテナつきの様子が変わってきましたね!
プロパティごと無いものを入れてみる
最後に、そもそもプロパティが無いものをいれてみましょう。ハテナがついていないものは全てエラーになってしまいました。
ちなみに引数無しは
最後といいましたが、引数無しはどうなるでしょうか。 答えはPlaygroundにはあります!
解説?
もう既に全て説明してしまった感もありますが、
型定義の?
はundefined
を許容し、かつ、プロパティそのものが未定義も許容する
となります。そもそもundefined
って日本語では未定義では...?って気持ちにもなりますが、そうなった方は参考資料を見てみて下さい(投げ)。
使い分け方の指針(あくまでこれは個人的なものです)
- 未定義や
undefined
の場合がある時は、?
を使っておけばOK。-
|undefined
と書くより簡単 - 実用上問題ない(と思っている)
-
- どうしても明確に
undefined
と定義したい場合が思い付きませんでした。- 既存コードやライブラリの都合上...?
- 定義がある場合と定義がない場合を区別しつつ、かつ定義された値で
undefined
が特別な意味を持つ場合...? (nullは使わないと決めつつ、「設定項目を空っぽにした」みたいな状態に意味があるようなアプリの場合?)
参考資料
以下がとても詳しいため、より深く学びたい人、理論から学びたい人、そもそもundefinedとnullはどう使い分けるべきなのか?と思った人は是非読んでみましょう!
undefinedとnullの違い - サバイバルTypeScript
nullとundefined - TypeScript Deep Dive 日本語版
最後に
弊社ではだいたい月1回を目標に、エンジニア全体でトレーニングを実施しています。AWS JAMのようなグループワークと、座学多めの講義を隔月で行っています。
一緒に働く/一緒に成長するメンバーを募集中です!雰囲気だけでも是非知っていただきたく、↓のカジュアル面談を気楽にお申し込み下さい!
Discussion