Typescript 如何正确键入更新对象指定字段值的函数
我实现了一个函数,它接受对象、回调和包含该对象键的数组。此函数使用参数中提供的回调更新数组中指定的每个字段的值 例如:Typescript 如何正确键入更新对象指定字段值的函数,typescript,Typescript,我实现了一个函数,它接受对象、回调和包含该对象键的数组。此函数使用参数中提供的回调更新数组中指定的每个字段的值 例如: const foo = { a: 3, b: 4, c: 4 } const bar = updateFields(foo, (val) => val + 10, ['a', 'b']) console.log(bar) // { a: 13, b: 14, c: 4 } 现在我已经实现并测试了这个函数,所以它工作正常 const updateFields = <
const foo = { a: 3, b: 4, c: 4 }
const bar = updateFields(foo, (val) => val + 10, ['a', 'b'])
console.log(bar) // { a: 13, b: 14, c: 4 }
现在我已经实现并测试了这个函数,所以它工作正常
const updateFields = <T extends {}, K extends keyof T, V>(
obj: T,
callback: (val: T[K]) => V,
fields: K[]
) =>
Object.entries<T[K]>(obj).reduce(
(acc, [key, value]) => {
if (fields.includes(key as K)) {
acc[key] = callback(value)
} else {
acc[key] = value
}
return acc
},
{} as any
)
const updateFields=(
obj:T,
回调:(val:T[K])=>V,
字段:K[]
) =>
Object.entries(obj).reduce(
(acc,[键,值]=>{
if(字段包括(键为K)){
acc[键]=回调(值)
}否则{
acc[键]=值
}
返回acc
},
{}
)
我感兴趣的是如何正确地为这个函数编写类型,尤其是返回类型,因为现在我将它隐式地设置为
any
updateFields
将具有返回类型{[p in K]:V}&Omit
-将字段中的所有属性K
更新为值V
,同时保留其余属性
在reduce
操作中,如果一个新对象一个接一个地迭代构造,则总是需要某种形式的断言/强制转换。在具体示例中,您可以通过迭代字段
数组而不是T
的原始对象属性来简化函数体。这将把键保存为K
强制转换和条件逻辑
const updateFields = <T extends object, K extends keyof T, V>(
obj: T,
callback: (val: T[K]) => V,
fields: K[]
): Omit<T, K> & { [P in K]: V } => ({
...obj,
...fields.reduce(
(acc, cur) => {
// ... or use spread here
acc[cur] = callback(obj[cur]);
return acc;
},
{} as { [P in K]: V } // this cast is (almost always) necessary
)
});
const foo = { a: 3, b: 4, c: "foo" };
// const bar: Pick<{a: number; b: number; c: string}, "c"> & {a: number; b: number;}
const bar = updateFields(foo, val => val + 10, ["a", "b"]);
console.log(bar); // { a: 13, b: 14, c: "foo" }