在TypeScript 中,如果某個屬性可以從物件中省略,則該屬性被認為是可選的,這表示它可以是未定義的,也可以是根本不提供的。可選屬性使用 ? 表示屬性鍵上的後綴。確定屬性是可選的還是明確定義為 undefined 的類型可能非常棘手。
讓我們考慮以下具有五種可能組合的範例:
type Example = { required: number; optional?: number; requiredAsUndefined: undefined; requiredWithUndefined: number | undefined; optionalWithUndefined?: number | undefined; }
最後四個屬性允許未定義,但實際上只有第二個和第五個屬性是可選的。有趣的是,可選屬性、requiredWithUndefine 和OptionalWithUndefine 都解析為相同的聯合類型編號 |未定義。
所以,我們想要的是一個類型,對於可選和可選的帶未定義返回 true,對於其餘的返回 false。以下是此類實用程式類型的外觀:
type IsOptional<T, K extends keyof T> = undefined extends T[K] ? ({} extends Pick<T, K> ? true : false) : false; type Required = IsOptional<Example, 'required'>; // false type Optional = IsOptional<Example, 'optional'>; // true type RequiredAsUndefined = IsOptional<Example, 'requiredAsUndefined'>; // false type RequiredWithUndefined = IsOptional<Example, 'requiredWithUndefined'>; // false type OptionalWithUndefined = IsOptional<Example, 'optionalWithUndefined'>; // true
此實用程式類型有兩個限制。第一個約束 undefined extends T[K],檢查 undefined 是否可以是 T[K] 存取的類型的一部分。它本質上詢問類型 T[K] 是否可以包含 undefined。第二個限制 {} 擴充了 Pick
從這個實用程式類型中,我們可以建立一個新的映射類型,它只選擇可選屬性。非可選屬性將設定為 never:
type OptionalProperties<T> = { [K in keyof T]: IsOptional<T, K> extends true ? T[K] : never } type OnlyOptionals = OptionalProperties<Example>; // type OnlyOptionals = { // required: never; // optional?: number; // requiredAsUndefined: never; // requiredWithUndefined: never; // optionalWithUndefined?: number | undefined; // }
具有類型 never 的屬性通常足以保證類型安全,但如果我們確實想出於風格目的而省略這些屬性,我們可以將 IsOptional
type OnlyOptionals<T> = { [K in keyof T as IsOptional<T, K> extends true ? K : never]: T[K] } type OnlyOptionals = OnlyOptionals<Example>; // type OnlyOptionals = { // optional?: number; // optionalWithUndefined?: number | undefined; // }
這裡是直接在瀏覽器中嘗試的 Playground:TypeScript Playground
以上是可選與未定義:如何檢查可選屬性的詳細內容。更多資訊請關注PHP中文網其他相關文章!