[英]Generic function getting optional property value with default value
有一個 object 類型,如下面的X
。 請注意,所有屬性都是可選的,它們的類型不同,並且對於某些屬性, null
是一個有效值。
type X = {
a?: number | null;
b?: string;
c?: boolean | null;
};
現在,為了方便起見,我想制作一個 function 來獲取X
的屬性值之一。 function 可以接受默認值並在屬性缺失時返回它。
我寫的function如下:
function get<K extends keyof X>(k: K, x: X, defaultValue: Required<X>[K]): Required<X>[K] {
const v = x[k];
return v !== undefined ? v : defaultValue;
}
因為屬性是可選的,所以我使用Required<X>[K]
來獲取有效的屬性類型(不包括undefined
)。
我的預期結果是:
// a: number | null = 12345
const a = get('a', {}, 12345);
// b: string = 'bar'
const b = get('b', { b: 'bar' }, '?');
// c: boolean | null = null
const c = get('c', {}, null);
但是我在get
function 的返回語句中得到了以下編譯器錯誤。
Type 'Required<X>[K] | (X[K] & ({} | null))' is not assignable to type 'Required<X>[K]'.
Type 'X[K] & null' is not assignable to type 'Required<X>[K]'.
Type 'X[K] & null' is not assignable to type 'never'.
我猜 function 中有錯誤(可能與Required
的使用有關),但我無法解決。
謝謝你。
當您測試v !== undefined
TypeScript 時,會將v
的類型縮小為X[K] & ({} | null)
。 此交集類型使用交集從值類型中排除未定義。
Required<X>[K]
做類似的事情,但實際上有一個極端情況,當屬性類型包含undefined
時,它不會從K
中刪除undefined
,但該屬性不是可選的:
//number | undefined
type XX = Required<{ o: undefined | number }>['o']
即使Required<X>[K]
比X[K] & ({} | null)
更寬松(允許X[K] - optional undefined
)TypeScript 將無法按照映射類型得出此結論。
最簡單的解決方案是定義一個NotUndefined
undefined,類似於 TypeScript 從v
中排除undefined
的方式,我們可以將其用於返回值和defautlValue
參數:
type NotUndefined<T> = T & ({} | null)
function get<K extends keyof X>(k: K, x: X, defaultValue: NotUndefined<X[K]>): NotUndefined<X[K]> {
const v = x[k];
return v !== undefined ? v : defaultValue;
}
如果該屬性是必需的,並且它的類型中顯式undefined
,則上面的版本不允許默認值undefined
(例如{ d: boolean | null | undefined; }
)。
您可以保留原始行為,方法是將defaultValue
恢復為Required<X>[K]
並將其添加到與NotUndefined<X[K]>
的聯合中以返回類型:
function get<K extends keyof X>(k: K, x: X, defaultValue: Required<X>[K]): Required<X>[K] | NotUndefined<X[K]> {
const v = x[k];
return v !== undefined ? v : defaultValue;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.