Lodash _.reduce()“预期2-3个参数,但得到2个” TypeScript错误

时间:2018-09-01 17:57:15

标签: typescript lodash

我正在尝试将其中的一项测试中的ListAdItemResponse[]集合类型减少为{[name: string]: Date}类型,并检查每个后续发布日期都在当前日期之前(例如,按publishedAt降序排列):

 _.reduce<ListAdItemResponse, {[name: string]: Date}>(
   data,
   (result, val) => {
     expect(new Date(val.publishedAt)).to.be.beforeTime(
       new Date(result.publishedAt),
      )
     return {publishedAt: val.publishedAt}
   })

使用TypeScript 2.9.2,我得到了这个奇怪的矛盾错误(“预期有2-3个参数,但有2个”)。根据Lodash的文档,第三个参数是可选的,但是无论尝试如何,我都无法克服此错误。知道这里可能有什么问题吗?谢谢。

P.S。编译没有错误,但是很明显破坏了我的测试:

_.reduce<ListAdItemResponse, {[name: string]: Date}>(
  data,
  (result, val) => {
    expect(new Date(val.publishedAt)).to.be.beforeTime(
      new Date(result.publishedAt),
    )
    return {publishedAt: val.publishedAt}
  }, {}) // with {} added as 3rd argument

更新9/2/18:

按照@Matt的建议,我尝试了这种方法,但是这次出现了3个编译错误。看起来现在的alis.data集合类型应该是{[name: string]: Date}而不是ListAdItemResponse[]

_.reduce<{[name: string]: Date}>(
  alis.data, // <-- error 1: Argument of type 'ListAdItemResponse[]' is not assignable to parameter of type '{ [name: string]: Date; } | null | undefined'.Type 'ListAdItemResponse[]' is not assignable to type '{ [name: string]: Date; }'. Index signature is missing in type 'ListAdItemResponse[]'.
  (result, val) => { // <-- errors 2,3: Parameter 'result' implicitly has an 'any' type. Parameter 'val' implicitly has an 'any' type.
    expect(new Date(val.publishedAt)).to.be.beforeTime(
      new Date(result.publishedAt),
    )
    return {publishedAt: val.publishedAt}
  })

1 个答案:

答案 0 :(得分:1)

如果要省略第三个参数,那么输入项和累加器的类型应该相同,因此,您应该仅传递一个类型参数:

_.reduce<{[name: string]: Date}>(...)

我向an issue提出了矛盾的错误消息。

第二回合

即使错误数量增加了,您也更加接近目标!假设ListAdItemResponse的定义如下:

interface ListAdItemResponse {
    publishedAt: Date;
    // other fields...
}

然后,您对_.reduce的调用与您打算的重载不匹配,因为ListAdItemResponse无法分配给{[name: string]: Date},因为它没有索引签名。 (令人困惑的是,TypeScript的错误#1是基于一个错误的假设,即您想要一个不同的重载,该重载意在减少对象的键。)对象文字类型有一个特殊的例外,例如您从化简器返回的类型。您可能应该做的就是将状态类型更改为{publishedAt: Date},因为这是您唯一使用的字段:

_.reduce<{publishedAt: Date}>(...)

这也会使错误2和错误3也消失。