【TypeScript】オプショナルプロパティについて解説
こんにちは、めんだこです!
今回は、TypeScriptのオプショナルプロパティについて解説していきます。
それでは早速、オプショナルプロパティの使用法とその注意点について学んでみましょう。
オプショナルプロパティとは
オプショナルプロパティは、TypeScriptのオブジェクト型の機能で、端的に言えば
「あるかもしれないし、ないかもしれない」プロパティを表すためのものです。
Userオブジェクトの型を定義した、次のコードを見てみましょう。
type User = {
name: string;
age?: number; // オプショナルプロパティ
};
これは、次のどちらの宣言も許容します。
const chirlie: User = {
name: "chirlie",
age: 32,
};
const matt: User = {
name: "matt",
};
オプショナルプロパティは、実質的にオプショナルなプロパティにundefinedを許容する形で認識させます。
(age?: number と age?: number | undefined は同じ)
よって、User型は次のユーザーも受け入れます。
const rose: User = {
name: "rose",
age: undefined,
};
exactOptionalPropertyTypesについて
先ほど見た、オプショナルプロパティでは、明示的にundefinedを代入することができていましたが、TypeScriptのコンパイラオプションの一つであるexactOptionalPropertyTypesでは、これを禁止します。
このプロパティは、デフォルトで無効化されていますが、公式で
exactOptionalPropertyTypes makes TypeScript truly enforce the definition provided as an optional property
https://www.typescriptlang.org/tsconfig/#exactOptionalPropertyTypes
意訳: exactOptionalPropertyTypes は、TypeScript がオプショナルプロパティとして提供された定義を真に強制するようにします。
と言われているように、オプショナルプロパティの意図を明確にすることができるので、有効化は推奨されます。
実際に設定して、先ほどのコードを見てみましょう。
{
"compilerOptions": {
// 省略
"exactOptionalPropertyTypes": true
},
// 省略
}
type User = {
name: string;
age?: number;
};
const chirlie: User = {
name: "chirlie",
age: 32,
};
const matt: User = {
name: "matt",
};
/**
* error: Unable to compile TypeScript:
* Type '{ name: string; age: undefined; }' is not assignable to type 'User' with 'exactOptionalPropertyTypes: true'.
* Consider adding 'undefined' to the types of the target's properties.
* Types of property 'age' are incompatible.
* Type 'undefined' is not assignable to type 'number'.
*/
const rose: User = {
name: "rose",
age: undefined, // 明示的なundefined指定
};
先ほどはroseは正常に定義できていましたが、今回は、ageに明示的にundefinedを指定していることが、[exactOptionalPropertyTypes]の規約に違反しているため、コンパイル時にエラーが発生しています。
明示的なundefinedを許容する記法
exactOptionalPropertyTypesを有効化しても、undefinedを許容するためには、型定義の際にUnion型でundefinedも一緒に指定する必要があります。
この場合、プロパティ自身をオプショナルとするかしないかの2通りの書き方が可能です。
- オプショナルとした場合(age?:) ageプロパティは省略可能
- オプショナルとしない場合(age:) ageプロパティは省略不可
// オプショナルとした場合
type User = {
name: string;
age?: number | undefined // 省略可能
};
// オプショナルとしなかった場合
type User = {
name: string;
age: number | undefined // 省略不可
};
ageプロパティをオプショナルとした場合は、省略可能なため利便性に優れる一方で、
- ageを省略した
- ageを書き忘れた
のどちらか区別できない、という欠点も持っています。
よって、省略することに対して大きな利点がない場合は、あえてオプショナルとしない方が適していると言えるでしょう。
まとめ
今回は、TypeScriptのオプショナルプロパティについて解説しました。
オプショナルプロパティは、プロパティが存在するかどうか不確定な状況で使う便利な機能です。しかし、exactOptionalPropertyTypesを有効にすることで、意図しないundefinedの代入を防ぐことができます。
明示的にundefinedを許容する場合には、Union型を使用して対応しましょう。
オプショナルなプロパティの使い方をしっかり理解し、適切な場面で使い分けることが大切です。
参考
こちらの記事の執筆にあたり、以下のWebサイト・書籍を参考・利用させていただきました。
ありがとうございました!
【Webサイト】
- TypeScript: TSConfig Reference – Docs on every TSConfig option (Microsoft)
- exactOptionalPropertyTypes | TypeScript入門『サバイバルTypeScript』 (Open Souce)
【書籍】
- プロを目指す人のためのtypescript入門(著者: 鈴木 僚太, 発行所: 株式会社 技術評論社, 発行日: 2022.05)
ご覧いただきありがとうございました。
より良い記事を提供するため、この記事に対するご指摘・ご感想等ございましたら随時コメントを募集しております。
お気軽に書き込みくださいませ。