Arrays 管道变换对对象数组使用reduce

Arrays 管道变换对对象数组使用reduce,arrays,angular,typescript,pipe,reduce,Arrays,Angular,Typescript,Pipe,Reduce,这是我的接口文件: export interface ListCount { centre?: string; cause?: string; totalTime?: number; } 我正在尝试使用管道变换将对象还原为数组: export class SumPipe implements PipeTransform { transform(items: ListCount[], attr: string): number { return items.reduce(

这是我的接口文件:

export interface ListCount {
  centre?: string;
  cause?: string;
  totalTime?: number;
}
我正在尝试使用管道变换将对象还原为数组:

export class SumPipe implements PipeTransform {
  transform(items: ListCount[], attr: string): number {
    return items.reduce((a, b) => a + b[attr], 0);
  }
}
在compenthtml中,我想计算totalTime的总和

{{ (delayCount$ | async) | sum:'totalTime'}}
但我有一个错误:

error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'ListCount'.
error TS2365: Operator '+' cannot be applied to types 'number' and 'string | number'.
然后我将参数
attr:string
更改为
attr:keyof ListCount
还有这个错误:

error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'ListCount'.
error TS2365: Operator '+' cannot be applied to types 'number' and 'string | number'.


请提供任何帮助

好的,这样您的代码编译时就不会出现问题并且可以正常工作。这是一场有效的闪电战。如果在本地环境中失败,可以尝试检查TS版本,尝试重新启动Angular CLI,查找其他问题,或者至少查找引发错误的行上提供的信息

不过,您的代码存在一些问题

  • 正如其他人所指出的,将any
    attr
    传递到管道并使用括号表示法获取属性值毫无意义。管道接受的唯一对象是
    ListCount[]
    ,因此它必须是
    totalTime
    ,因为它是唯一的数值属性,所以必须求和。不过,如果您制作了更通用的管道,可以接受
    any[]
    ,这将是有意义的

  • 您的管道没有针对您的用例进行保护
    totalTime
    是一个可选属性,这意味着如果任何项目没有定义
    totalTime
    (根据您的界面,它可以定义),管道将返回
    NaN
    。不确定这是不是你想要的行为


    • 我建议如下:

      • 将attr限制为指向数值属性
      • 考虑到属性可以是可选的。用零表示那些
      • 或者过滤掉缺失(未定义)的值
      导出接口列表计数{
      中心?:弦;
      原因:字符串;
      totalTime?:数字;
      其他时间:数字;
      }
      键入数字键={
      [P in keyof T]:T[P]扩展数字?P:从不;
      }[keyof T];
      键入NumericListCountKey=NumericKeys;
      污水管{
      转换(项:ListCount[],属性:NumericListCountKey):编号{
      常量elemes=items.map(elem=>elem[attr]);
      返回elemes.reduce((prev:number,currentVal)=>prev+(currentVal?currentVal:0),0);
      }
      }
      //或者,使用过滤器
      第2类{
      静态isNumber(n:number |未定义):n是数字{
      返回n!=null;
      } 
      转换(项:ListCount[],属性:NumericListCountKey):编号{
      常量elems=items.map(elem=>elem[attr])
      .过滤器(SumPipe2.isNumber);
      返回元素reduce((prev:number,currentVal)=>prev+currentVal,0);
      }
      }
      

      根据文章,
      reduce()
      有一个可选索引,指向数组中的当前索引。知道这一点,我会选择下面的解决方案,完全忽略
      attr

      return items.reduce((a, b, index) => a + b[index].totalTime, 0);
      

      为什么不
      attr
      transform(items:ListCount[],attr:number):number{
      @er sho:因为它是要求和的属性名。当它是唯一的类型(
      number
      )时,传递
      totalTime
      的目的是什么可以在数组中求和吗?以后是否会有任何其他类型的
      number
      属性?@er sho:property
      totalTime
      中包含的值是
      number
      类型。但是在尝试使用
      obj['totalTime']
      访问属性的上下文中,
      totalTime
      是一个字符串。try
      reduce((a:编号,b:任意)=>…)