我有一個通用函式,它將回傳通用型別的物件或 null(可能未定義),所以我添加| null | undefined到回傳型別,但它似乎沒有得到應用:
const test = <T>(obj: TypeA<T>): T | undefined | null => {
return someObject[obj];
};
當我查看生成的函式定義時const test: <T>(obj: TypeA<T>) => T(沒有 null 或 undefined)。這也意味著如果我這樣稱呼它:
test<number>(someNullArg).toPrecision()
TypeScript 不會抱怨,即使它應該并且即使代碼Cannot read properties of null在運行時拋出錯誤。如果我替換泛型型別,則正確生成回傳型別 ( const test: (obj: TypeA<any>) => any | undefined | null)。
更新
這是實際實作的簡化版本:
let value;
const get = <T>(obj: Promise<T>): T | undefined | null => {
obj.then(val => value = val);
return value;
}
它接受一個 Promise 并回傳它的值(如果它被解決了)。它旨在用于StencilJS 組件中,以在同步渲染方法中輸出異步值。基本上我正在嘗試重新創建Angular 的asyncpipe的功能。
第二次更新
我試圖進一步除錯它,我認為這可能是 TypeScript 中的一個錯誤。
我把它簡化為一個更簡單的例子:
function test<T>(): T | undefined | null {
return (window as any).foo;
}
const x = test(); // type is "unknown"
const y = test<number>(); // type is "number"
y.toFixed(); // should throw a type error but doesn't
顯然,| undefined | null一旦決議了泛型型別,就完全被忽略了,我不知道為什么,因為回傳型別非常具體。
這是整個源代碼(重要的部分是async函式)。
uj5u.com熱心網友回復:
為了應對這種正確,我建議您啟用的--strictNullChecks編譯器選項與任何隨之而來的錯誤,它的標志和交易。(我會更進一步說,使整個--strict編譯器功能套件能夠從語言中獲得“標準”數量的型別安全。)實際上,TypeScript 手冊說“我們總是建議人們strictNullChecks在可行的情況下打開他們的代碼庫。”
與--strictNullChecks關斷,所述null和undefined型別是每個其它型別的亞型; 任何型別T將接受型別的值null或undefined等形成聯盟的T有null或undefined僅相當于T。所以null和undefined行為相同的never型別,并且被吸收到工會所有。這被稱為“子型別縮減”,TypeScript 做了很多事情。
只有--strictNullCheckson 編譯器才有機會跟蹤null和undefined.
你可以做的是,如果你使用的是引數的--declaration編譯器選項發出.d.ts宣告檔案被別人包括你的代碼作為一個模塊來使用,發出的宣告可能不準確,如果編譯器急切地降低T | null | undefined到T,因為消費應用程式可能有--strictNullChecks 啟用,然后他們就會錯誤地認為get()總是T從 a回傳aPromise<T>而不是可能的undefinedor null。
你是對的。這被認為是 TypeScript 的設計限制,如microsoft/TypeScript#18773 中所述。正如那里提到的,“當我們發出.d.ts檔案時,null任何給定型別的特性早已不復存在。我們基本上必須假裝 [ --strictNullChecks] 作為一個完全獨立的編譯階段打開,因為它可能會改變任何型別的結果。 ” 由于這會導致編譯時間在--strictNullChecks關閉和--declaration打開時基本上翻倍,因此他們不會這樣做。
由于他們無法解決這個問題,--strictNullChecks如果您正在.d.ts為代碼生成檔案,您真的應該打開。不使用的消費者--strictNullChecks不會關心任何一種方式,但那些使用的人會欣賞它。
總之,雖然,null和undefined被當吸收到工會--strictNullChecks被禁用如預期運行,而不是一個錯誤。你可能想提交功能要求做到這一點不太急切地讓null和undefined型別在更多的情況下保存下來,但我不希望的TS團隊來實作它,即使它不會立即下降。
這是在精神上類似的問題是微軟/打字稿#29729,其中包含一個工會string和其他字串字面型別就像"a" | "b" | string是亞型減少到了string。有些人希望"a" | "b" | string保持原樣以用于自動完成和檔案目的,但編譯器將其"a" | "b" | string視為“一種奇特的寫作方式string”。因此,我希望“T | null | undefined出于檔案目的而保持原樣”形式的任何請求都將被拒絕或關閉,作為設計限制,并附上一條T | null | undefined只是“一種奇特的寫作方式”的注釋T。???♂?
uj5u.com熱心網友回復:
這個怎么樣...
let value;
function get<T>(obj: Promise<T>): T | undefined | null {
obj.then(val => value = val);
return value;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/368249.html
上一篇:無法用??轉換JS到TS
