[英]How can I return a NonNullable type in Typescript?
我有類似於以下的代碼:
interface Stuff {
foo: number | null;
bar: string | null;
}
let stuff: Stuff;
function getStuff(): Stuff;
function getStuff<K extends keyof Stuff>(key: K): NonNullable<Stuff[K]>;
function getStuff<K extends keyof Stuff>(key?: K): Stuff | NonNullable<Stuff[K]> {
if (key == null)
return stuff;
const value = stuff[key];
if (value == null)
throw new Error(`${key} is null`);
return value;
}
const myStuff = getStuff('foo');
顯然,當你到達getStuff
的最后一行時, getStuff
value
不能為null
或undefined
,但 Typescript 給出了這個錯誤:
Type 'Stuff[K]' is not assignable to type 'Stuff | NonNullable<Stuff[K]>'.
Type 'string | number | null' is not assignable to type 'Stuff | NonNullable<Stuff[K]>'.
Type 'null' is not assignable to type 'Stuff | NonNullable<Stuff[K]>'.
Type 'Stuff[K]' is not assignable to type 'Stuff'.
Type 'string | number | null' is not assignable to type 'Stuff'.
Type 'null' is not assignable to type 'Stuff'.(2322)
如果我刪除NonNullable
,那么它可以正常工作,但當然myStuff
將需要一個空檢查,這是我在這里試圖避免的。 即我知道這里的value
不能為null
,但是我如何正確地讓 Typescript 知道,沒有“作弊”,例如通過return value!
?
最終將以下 util 添加到我們的項目中,帶有斷言和輔助類型(因此我們可以在代碼中編寫Null
而不是null | undefined
一堆地方)
// util/null
type Null = null | undefined;
export default Null;
export function isNotNull<T>(value: T)
: value is NonNullable<T> {
return value != null;
}
export function assertNotNull<T>(value: T, throwError: (value: T) => never)
: asserts value is NonNullable<T> {
if (value == null) throwError(value);
}
您可以簡單地進行類型斷言 - return value as NonNullable<Stuff[K]>
,或者引入自定義類型保護。
您面臨的問題是 TS 沒有將您的控制流空檢查范圍縮小到NonNullable
,但是通過自定義類型保護您可以強制執行它。 考慮:
// type guard narrows to NonNullable
function isNonNullable<T>(a: T): a is NonNullable<T> {
return a !== null
}
function getStuff(): Stuff;
function getStuff<K extends keyof Stuff>(key: K): NonNullable<Stuff[K]>;
function getStuff<K extends keyof Stuff>(key?: K): Stuff | NonNullable<Stuff[K]> {
if (key == null)
return stuff;
const value = stuff[key];
if (isNonNullable(value)) {
return value;
}
throw new Error(`${key} is null`);
}
請注意isNonNullable
是通用類型保護,您可以將其與任何其他值一起使用。
反向條件也將正常工作:
if (!isNonNullable(value)) {
throw new Error(`${key} is null`);
}
return value;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.