使用通用功能時,打字稿有問題
export const createNewArray = <T>(
arr: T[],
keyId: keyof T,
keyTitle: keyof T,
) : [] | TValue[] => {
const arrayAfterMap = arr.map((item) => ({name: item[keyTitle], id: item[keyId]}));
if(arrayAfterMap.every(item => (typeof item?.id === "string" || typeof item?.id === "number" ) && (typeof item?.name === "string"))) {
console.log(arrayAfterMap);
return arrayAfterMap
}
return []
};
此函式接受陣列并回傳新陣列。只是零陣列或帶有物件 TValue 的陣列
export type TValue = {
name: string
id: string | number
}
但我收到打字稿錯誤 - TS2322。
TS2322: Type '{ name: T[keyof T]; id: T[keyof T]; }[]' is not assignable to type '[] | TValue[]'.
Type '{ name: T[keyof T]; id: T[keyof T]; }[]' is not assignable to type 'TValue[]'.
Type '{ name: T[keyof T]; id: T[keyof T]; }' is not assignable to type 'TValue'.
Types of property 'name' are incompatible.
Type 'T[keyof T]' is not assignable to type 'string'.
Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'string'.
Type 'T[string]' is not assignable to type 'string'.
在字串中——“return arrayAfterMap”
我不明白我做錯了什么。我檢查了是否符合 TValue。如果檢查通過,那么我在 map 之后回傳陣列,如果沒有,則為空。但這是行不通的。我會很高興任何建議!
我在codesandbox上做了一個測驗應用程式,這樣你就可以看到代碼了。但是codesandbox不會立即顯示此錯誤 -鏈接
uj5u.com熱心網友回復:
解決這個問題的最簡單方法可能是型別保護:
const isTValueArray = (arr: any[]): arr is TValue[] => arr.every(item =>
(typeof item?.id === "string"
|| typeof item?.id === "number" )
&& (typeof item?.name === "string")
)
呼叫函式后,您可以回傳arrayAfterMap正確的型別:
if(isTValueArray(arrayAfterMap)) {
return arrayAfterMap
}
更復雜的方法是為函式的每個鍵添加兩個更通用的型別:
export const createNewArray = <
T extends {[keyId in KeyId]: string} // T[KeyId] should be string
& {[keyTitle in KeyTitle]: string | number},
KeyId extends keyof T,
KeyTitle extends keyof T>(
arr: T[],
keyId: KeyId,
keyTitle: KeyTitle,
) : TValue[] => {
const arrayAfterMap = arr.map((item) => ({name: item[keyTitle], id: item[keyId]}));
return arrayAfterMap
};
在這里,TypeScript 會自動知道arrayAfterMap相當于TValue[].
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/466993.html
