假設我有以下代碼:
interface Response { 'property.a': number; 'property.b': string }
const response: Response = {
'property.a': 10,
'property.b': 'foo'
}
我想以response型別安全的方式訪問 的屬性,但它并沒有像我預期的那樣完全作業。我正在尋找的是一種使用字串訪問物件屬性的方法,其中
- 如果物件具有屬性,訪問它會給出正確的型別
- 如果物件沒有該屬性,則訪問它會引發錯誤
如果您直接訪問屬性,則會發生以下情況:
response['property.a'] // works as expected: is of type number
response['property.c'] // should throw an error, but doesn't
所以條件1滿足,但條件2不滿足。我還嘗試了以下方法:
const get = <T>(obj: T, key: keyof T) => obj[key]
get(response, 'property.a') // should be of type number, but is number | string;
get(response, 'property.c') // works as expected: throws error
所以至少會拋出錯誤,但現在它回傳所有可能的屬性型別的聯合Response- 此方法在條件 1 上失敗,但滿足條件 2。
有沒有同時滿足這兩個條件的方法?
編輯:
我剛剛發現有一個稱為noImplicitAny啟用這種行為的 TypeScript 規則!不幸的是,我無法在我目前正在使用的代碼庫中啟用此規則,因此我將保持這個問題開放,以防有其他解決方法。
uj5u.com熱心網友回復:
對于直接屬性訪問,除非您沒有啟用編譯器選項,--noImplicitAny否則您肯定會遇到錯誤,這是“標準”--strict編譯器選項套件的一部分。幾乎普遍建議啟用--strict.
考慮你的get()功能方法:
由于keyis 屬于 型別keyof T,thenobj[key]將屬于索引訪問型別 T[keyof T],它將是中所有已知屬性型別的聯合T。
如果您想跟蹤作為引數傳入的特定鍵的文字型別,那么您的函式需要在該型別中是通用的,如下所示:keyget()
const get = <T, K extends keyof T>(obj: T, key: K) => obj[key]
Nowkey是泛型型別,被K 限制為keyof T,并被obj[key]推斷為索引訪問型別T[K]。讓我們測驗一下:
const num = get(response, 'property.a');
// const num: number
在這里,T被推斷為Response,K被推斷為"property.a",T[K]也是number, 如所期望的那樣。
Playground 代碼鏈接
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/524770.html
標籤:打字稿
下一篇:在反應中制作動態頁面
