我有一個方法,它接受一個 Partial 物件,我想使用 Object.entries 迭代該物件,然后根據我想執行一些操作的鍵。該介面的鍵是字串,但值是字串|數字|字串[]|日期時間。我希望我傳遞給它的函式知道從密鑰傳遞的內容。
我目前擁有的代碼是
public partialUpdate = async (id: number, fieldsToUpdate: Partial<IClient>) => {
type temp = Partial<Record<keyof IClient, (val : string) => void>>;
const mapping : temp = {
name: (val) => client.setName(val),
website: (val) => client.setWebsite(val),
sic_codes: (val) => client.setSicCodes(val),
phone_number: (val) => client.setPhoneNumber(val),
};
Object.entries(fieldsToUpdate).forEach(([key, value]) => mapping[key](value));
return this.clientRepository.update(id, client);
};
界面是
export interface IClient
{
id: number,
creation_date: DateTime,
name:string,
website:string,
phone_number:string,
industry:string,
sic_codes:string[],
}
我目前遇到的問題是,如果它都是字串型別,那么沒有問題,但由于 sic_codes 是一個字串 [],它會導致型別錯誤。有沒有辦法讓 const 映射知道鍵的型別 val 是什么?
uj5u.com熱心網友回復:
您的原始型別
Record<keyof IClient, (val: string) => void>
使用實作為映射型別的Record<K, V>實用程式型別。讓我們根據映射型別明確地寫出來:
{[K in keyof IClient]: (val: string) => void}
所以,這里的問題是val型別string不一定是IClient每個鍵K的值型別keyof IClient。修復方法是替換string為IClient[K]索引訪問型別IClient,表示“鍵的值型別K”:
type Test = { [K in keyof IClient]: (val: IClient[K]) => void };
/* type Test = {
id: (val: number) => void;
creation_date: (val: Date) => void;
name: (val: string) => void;
company_number: (val: string) => void;
website: (val: string) => void;
phone_number: (val: string) => void;
industry: (val: string) => void;
sic_codes: (val: string[]) => void;
} */
看起來挺好的。
如果我們將其插入您原來的型別,仍然存在錯誤。 Object.entries()沒有足夠強的型別來滿足您在 TypeScript 中想要的作業。有關更多資訊,請參閱此 SO 問題。你可以給它更強的型別(即使這不是 100% 安全的)。即使您這樣做,您的forEach()回呼也需要在您正在處理的特定鍵型別中是通用的。在該回呼中,如果您想安全,K您需要確保 yourvalue和 your mapping[key]are not :undefined
讓我進行這些更改,只是為了表明它可以按您的意愿作業:
// Give stronger typings to Object.entries()
type Entry<T extends object> = { [K in keyof T]-?: [K, T[K]] }[keyof T];
function entries<T extends object>(obj: T) {
return Object.entries(obj) as Entry<T>[];
}
const partialUpdate = async (id: number, fieldsToUpdate: Partial<IClient>) => {
const client = new Client();
const mapping: Partial<{ [K in keyof IClient]: (val: IClient[K]) => void }> = {
name: (val) => client.setName(val),
company_number: (val) => client.setCompanyNumber(val),
industry: (val) => client.setIndustry(val),
sic_codes: (val) => client.setSicCodes(val),
};
const e = entries(fieldsToUpdate).forEach(<K extends keyof IClient>(
[key, value]: [K, IClient[K] | undefined]) => value && mapping[key]?.(value));
return null;
};
萬歲,沒有錯誤!
Playground 代碼鏈接
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/480196.html
