exactOptionalPropertyTypes
exactOptionalPropertyTypes là compiler option cấm gán undefined cho optional property.
- Mặc định:
false - Phiên bản thêm vào: 4.4
- TypeScript khuyến nghị nên bật
Giải thích
Trước đây, optional modifier cho phép không chỉ bỏ qua việc set giá trị mà còn có thể set undefined một cách có chủ đích.
tsinterfaceUser {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",};
tsinterfaceUser {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",};
Giá trị chưa được định nghĩa và giá trị là undefined có hành vi khác nhau. Ví dụ điển hình là Object.keys(), khi áp dụng lên user1, user2, user3 ở trên, kết quả sẽ như sau:
ts// user1["name", "nationality"];// user2["name", "nationality"];// user3["name"];
ts// user1["name", "nationality"];// user2["name", "nationality"];// user3["name"];
Sự khác biệt này có thể gây ra lỗi runtime không mong muốn. Nếu giá trị được set đúng (trong trường hợp này là 'India' | 'China') thì nationality nên có trong Object.keys(), nhưng khi là undefined thì vẫn cần phải check sự tồn tại của giá trị ở phía sau.
Khi bật option này, các key có optional modifier trong interface, type sẽ không được phép có key với giá trị undefined. Trong ví dụ trước, user2 gán undefined sẽ báo lỗi như sau:
tsinterfaceUser {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",};
tsinterfaceUser {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",};
Nếu thực sự muốn key có thể nhận giá trị undefined, hãy thêm union type với undefined vào ngoài optional modifier.