[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