Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 是否可以减少typescript中具有未知属性名的泛型对象?_Javascript_Typescript_Functional Programming - Fatal编程技术网

Javascript 是否可以减少typescript中具有未知属性名的泛型对象?

Javascript 是否可以减少typescript中具有未知属性名的泛型对象?,javascript,typescript,functional-programming,Javascript,Typescript,Functional Programming,是否有可能通过对两个对象的属性求和,将它们简化为一个,就像对任何通用对象那样 const A = {x:1, y:1, z:1} const B = {x:2, y:2, z:2} // result {x:3, y:3, z:3} 我希望得到一些功能 function reduceObjects<T extends {[readonly key: string]: number}>(previousObject:T, currentObject:T) => T 函数还原对

是否有可能通过对两个对象的属性求和,将它们简化为一个,就像对任何通用对象那样

const A = {x:1, y:1, z:1}
const B = {x:2, y:2, z:2}
// result {x:3, y:3, z:3}
我希望得到一些功能

function reduceObjects<T extends {[readonly key: string]: number}>(previousObject:T, currentObject:T) => T
函数还原对象(以前的对象:T,当前对象:T)=>T
当我尝试这个解决方案时

function reduceObjectsGeneric<T extends {readonly [key: string]: number}>(currentValue: T , previousValue: T): T {
  const result = Object.assign({}, previousValue);


  Object.keys(previousValue).forEach((k) => {
    // eslint-disable-next-line functional/immutable-data
    result[k]=previousValue[k]+currentValue[k]
  })

  return result
}
函数约简对象通用(当前值:T,先前值:T):T{
const result=Object.assign({},previousValue);
Object.keys(previousValue).forEach((k)=>{
//eslint禁用下一行功能/不可变数据
结果[k]=以前的值[k]+当前值[k]
})
返回结果
}
我在内部循环中得到以下错误

类型“string”不能用于索引类型“{}&T”。ts(2536)


实现这种行为的功能性方法是什么?

功能性方法是(但可能不是干净的)

函数约简对象(a:T,b:T):T{
返回对象。键(a)。减少(
(acc,key)=>Object.assign(acc,{[key]:a[key]+b[key]}),
B
);
}
首先,使用
object.keys
获取对象“a”的键。
然后使用JavaScript的
数组.reduce
方法迭代键并将其分配给“acc”对象的“key”。

另一种方法使用只读函数方法,通过大多数es lint规则:

function reducer<T extends {readonly [key: string]: unknown|number}>(object1: Partial<T>, object2: Partial<T>): T {
  return Array.from(new Set([...Object.keys(object1),...Object.keys(object2)]).values()).reduce(
    (p: T, c: string) => {
      if ((object1[c] instanceof Object)) {
        return { [c]: reducer(object1[c] as Partial<T>, (object2[c] ?? {}) as Partial<T>),...p}
      }
      const v1 = object1[c]??ZERO
      const v2 = object2[c]??ZERO
      return {[c]: (v1 as number)+(v2 as number),...p,}
    }, {} as T
  )
}
函数缩减器(object1:Partial,object2:Partial):T{
返回Array.from(新集合([…Object.keys(object1),…Object.keys(object2)]).values()).reduce(
(p:T,c:string)=>{
if((object1[c]对象实例)){
返回{[c]:reducer(object1[c]作为Partial,(object2[c]??{})作为Partial),…p}
}
常数v1=object1[c]??零
常数v2=object2[c]??零
返回{[c]:(v1为数字)+(v2为数字),…p,}
},{}as T
)
}

一个通用的
减速器可以提供必要的支架:


type ReduceObjectsWith = <
  V extends unknown, T = Record<PropertyKey, V>
>(fn: (acc: T, pair: [PropertyKey, V]) => T) => (...objs: T[]) => T;

type ReduceWithSum = ReduceObjectsWith<number>

欢迎来到堆栈溢出!请拿着(你得到了一枚徽章!)通读一下,尤其是你最好的选择是做你的研究,做相关的主题,然后试一试。如果你在做了更多的研究和搜索后陷入困境,无法摆脱困境,请发布一份你的尝试,并明确指出你陷入困境的地方。人们会很乐意提供帮助。感谢您添加您的尝试。我看到有一行代码用来抑制eslint错误。您是否也乐于使用类型断言,或者努力避免使用类型断言?(我认为后者是最佳实践,尽管对于这样一个孤立的函数,我可能很乐意使用它们。)我试图避免类型断言,因为我希望将此函数保留为任何对象的泛型,其基本上所有属性都是数字(或实现+运算符的任何对象)二进制
+
(需要两个操作数的
+
)是JavaScript中任何类型的“定义”,但将其操作数强制为数字或字符串;结果始终是数字或字符串。这已经融入到语言中(并且不会改变)。这是我花在它上的时间最接近的了,还需要两个类型断言(总共三个)使其工作。(第一个类型断言对我来说是合理的。)所以我问为什么需要第二个和第三个断言。我们可以重新开始这个问题吗?我不确定是谁结束了这个问题,因为我已经尽可能清楚地缩小了问题的范围,并且我提供了合理的想法。这对刚接触这个平台的人来说是非常不公平和令人沮丧的。