exactOptionalPropertyTypes
exactOptionalPropertyTypes
はオプションプロパティにundefined
の代入することを禁止するコンパイラオプションです。
- デフォルト:
false
- 追加されたバージョン: 4.4
- TypeScript公式が有効化推奨
解説
今までオプション修飾子は値を設定しないことに加えてundefined
を意図的に設定することができました。
ts
interfaceUser {name : string;nationality ?: "India" | "China";}constuser1 :User = {name : "Srinivasa Aiyangar Ramanujan",nationality : "India",};constuser2 :User = {name : "Sergei Vasilevich Rachmaninov",nationality :undefined ,};constuser3 :User = {name : "Yekaterina II Alekseyevna",};
ts
interfaceUser {name : string;nationality ?: "India" | "China";}constuser1 :User = {name : "Srinivasa Aiyangar Ramanujan",nationality : "India",};constuser2 :User = {name : "Sergei Vasilevich Rachmaninov",nationality :undefined ,};constuser3 :User = {name : "Yekaterina II Alekseyevna",};
値が未定義であることと値がundefined
であることは厳密には動作が異なります。たとえばObject.keys()
は最たる例で、上記のuser1, user2, user3
にそれぞれObject.keys()
を適用すれば結果は次のようになります。
ts
// user1["name", "nationality"];// user2["name", "nationality"];// user3["name"];
ts
// user1["name", "nationality"];// user2["name", "nationality"];// user3["name"];
この差異が意図しない実行時エラーを生むことがあります。意図する値が設定されていれば(この場合'India' | 'China'
)nationality
はObject.keys()
に含まれるべきですがundefined
のときは結局その先で値の存在チェックが必要になります。
このオプションを有効にするとinterface, type
でオプション修飾子を持つキーはその値がキー自体を持たないようにしなければなりません。先ほどの例ではundefined
を代入したuser2
で次のようなエラーが発生します。
ts
interfaceUser {name : string;nationality ?: "India" | "China";}constuser1 :User = {name : "Srinivasa Aiyangar Ramanujan",nationality : "India",};constType '{ name: string; nationality: undefined; }' is not assignable to type 'User' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. Types of property 'nationality' are incompatible. Type 'undefined' is not assignable to type '"India" | "China"'.2375Type '{ name: string; nationality: undefined; }' is not assignable to type 'User' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. Types of property 'nationality' are incompatible. Type 'undefined' is not assignable to type '"India" | "China"'.: user2 User = {name : "Sergei Vasilevich Rachmaninov",nationality :undefined ,};constuser3 :User = {name : "Yekaterina II Alekseyevna",};
ts
interfaceUser {name : string;nationality ?: "India" | "China";}constuser1 :User = {name : "Srinivasa Aiyangar Ramanujan",nationality : "India",};constType '{ name: string; nationality: undefined; }' is not assignable to type 'User' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. Types of property 'nationality' are incompatible. Type 'undefined' is not assignable to type '"India" | "China"'.2375Type '{ name: string; nationality: undefined; }' is not assignable to type 'User' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. Types of property 'nationality' are incompatible. Type 'undefined' is not assignable to type '"India" | "China"'.: user2 User = {name : "Sergei Vasilevich Rachmaninov",nationality :undefined ,};constuser3 :User = {name : "Yekaterina II Alekseyevna",};
どうしてもキーにundefined
も指定したい場合はオプション修飾子に加えてundefined
のユニオン型を付加してください。