我有一个状态对象和一个将与状态对象组合在一起的更新对象,尽管更新中的null
意味着删除,所以我不能只对它们执行{...a, ...b}
。
const obj = {
other: new Date(),
num:5,
str:"original string"
}
const objUpdate:Partial<typeof obj> = {
num:6,
str:"updated string"
}
任务:迭代更新对象并将其值应用于原始对象,这是我理想的做法:
Object.entries(objUpdate).forEach(([k,v])=>{
if (v === undefined) return;
if (v === null){
delete obj[k]; // <-
return;
}
obj[k] = v; // <-
})
但是在指定的行我得到一个错误No index signature with a parameter of type 'string' was found on type '{ other: Date; num: number; str: string; }'
。理想情况下,Typescript应该知道k
已经是keyof typeof objUpdate
(编辑:here's possibly why),但我想我可以明确指出:
Object.entries(objUpdate).forEach(([k,v])=>{
if (v === undefined) return;
if (v === null){
delete obj[k as keyof typeof objUpdate];
return;
}
obj[k as keyof typeof objUpdate] = v; // <-
})
在指示行,它抱怨Type 'string | number | Date' is not assignable to type 'never'. Type 'string' is not assignable to type 'never'.
1.在这种情况下,有没有办法帮助Typescript正确地推断打字?
1.有没有更好的方法来实现我正在努力实现的目标?
2条答案
按热度按时间hwamh0ep1#
动态删除对象上的键在JavaScript中速度很慢,而且会使TypeScript中的键入变得更加困难。最简单的方法是调整代码中引用状态的其他部分,以便它们检查值是否为
null
。就会有
使用这种方法,输入将 * 正常工作 *,并且状态更新 * 将 * 像
{...a, ...b}
一样微不足道。要键入初始状态,请将键Map到添加了
null
的新对象类型。如果代码的某个部分要求删除
null
属性来格式化对象(例如数据库查询),可以在发送对象之前 * 在必要时 * 创建一个新对象,而不是更改状态的形状。vsnjm48y2#
我接受的答案对大多数人来说很可能是正确的方法,但我只是找到了一种方法来让我最初的方法工作,并在这里提供它的完整性。
使用Transform union type to intersection type,然后将值v键入为
as UnionToIntersection<typeof obj[keyof typeof obj]>