TypeScriptにおける「hoge?: string」と「hoge: string | undefined」 の違い
最終更新日: 2025-01-11記事投稿日: 2025-01-11
概要
TypeScriptの型システムで紛らわしい概念の1つとして、「オプショナルプロパティ」とundefined
の扱いがあります。本記事では、これらの違いをまとめてみます。
オプショナルプロパティとは
以下のようにプロパティ名の後に「?」がついてるのがオプショナルプロパティ。
type OptionalType = { name?: string }
オプショナルプロパティには以下のような特徴があります。
- プロパティ自体が存在しなくてもOK
- この場合
name
はstring
またはundefined
になる
この特徴は一見、ユニオン型を使用した以下のような記述と同じに感じられますが、明確な違いがあります。
type UnionType = { name: string | undefined }
オプショナルプロパティとユニオン型を使用した書き方の違い
オプショナルプロパティとユニオン型を使用した書き方の違いをまとめると以下の表のようになります。
オプショナルプロパティ | ユニオン型を使用した書き方 | |
---|---|---|
プロパティが取りうる値 |
|
|
プロパティの存在の可否 | 存在しなくてもOK | 必ず存在しなければならない |
プロパティを省略した場合の挙動 | nameはundefinedと解釈される | コンパイルエラー |
文章だと分かりづらいのですが... お手元のコードエディターに以下コードを貼り付けると違いが一目瞭然です👀
type OptionalType = {
name?: string
}
type UnionType = {
name: string | undefined
}
const obj1: OptionalType = {}
const obj2: UnionType = {}
console.log(obj1)
console.log(obj2)
obj2
には存在しなければいけないname
プロパティが定義されていないのでエラーになります!(obj2
にname: undefined
を追加するとエラーは解消されるので気になる方は試してみてください👀)


まとめ
オプショナルプロパティとユニオン型を使用した書き方の使い分け方は以下のように考えれば良さそうです👀
?
: プロパティの存在自体が任意の値の場合| undefined
: プロパティは必ず存在していて欲しいが、値が未定義にもなりうる場合
TypeScriptのhoge?: string
とhoge: string | undefined
は似ているようで異なる概念です。使用箇所の要件や型の安全性を考慮し、適切に使い分けることが重要になります。