emahiro/b.log

日々の勉強の記録とか育児の記録とか。

TypeScript の Optional Property

TypeScriptにはObjectのもつpropertyに Optional Property という機能があります。

propertyに ? をつけることでそのpropertyがない場合もあるよということを表現することができます。

公式のドキュメントには以下のように記載されています。

  • Not all properties of an interface may be required. Some exist under certain conditions or may not be there at all.

ref. https://www.typescriptlang.org/docs/handbook/interfaces.html

あってもなくてもどちらの場合も許容する、propertyを宣言するときに使います。

それだけだと「じゃあそんなpropertyを明示的に宣言する必要があるのか?」とか「正規でpropertyを定義しておけばいいじゃん」となりますが(僕もそう思いました)、例えば以下のような必須でない補足情報を追記したり(case1)、propertyが入ってるケースにおいて型を制限したり(case2)するときに使います。

case1: 何か付加情報を追記したいが、それはoptionalな値であること

interface Person {
  name: string // 必須
  age: number // 必須
  extra?: object // optional
}

case2: propertyが入ってるケースに置いて型を制限する

interface UserAgent {
  os?: 'mac' | 'win'
}

このケースでは os propertyは 存在しないかもしれないが、存在する場合は mac or win という文字列のみ許容する という表現になります。

どちらのケースにおいても別に ? をつけなくてもいいと思いますし、つけない方がinterfaceの構造を厳密に定義することができます。

しかし、propertyがないcaseにinterfaceの構造レベルでコンパイルエラーが検出されますし、それだけのためにいらないproperty込でインスタンス化するようなことにもなると思います。

// case1
const person: Person = {name: 'bob', age: 20} //OK

// case1': extra propertyをrequiredにする
const person: Person = {name: 'bob', age: 20} //Error
const person: Person = {name: 'bob', age: 20, extra: {}} //OK

Optional Propertyを使わないケースでのPersonオブジェクトのインスタンス化は冗長です。

また、可読性の観点からも 存在しないかもしれない値だとinterfaceを見ればわかります。

Optional Propertyは Typescriptの表現力の高さを感じさせるものでした。