【问题标题】:TypeScript, how to properly use Array.prototype.reduce with GenericTypeScript,如何正确使用 Array.prototype.reduce 和 Generic
【发布时间】:2020-09-10 20:31:40
【问题描述】:

我正在尝试使用 Array.prototype.reduce 规范化一些数据。

我想知道为什么我可以打破reduce 函数中的“类型检查”。

这是我的界面。

interface Dict<T> {
  [key:string]: T;
}

interface InnerData {
  id: string;
  value: number;
}

interface RawData {
  innerData: InnerData[];
}

interface NormalizedData {
  innerData: Dict<InnerData>
}

以下是我打算如何使用这些接口的示例。

const rawData: RawData = {
  innerData: [
    {
      id: "ID_ONE",
      value: 1
    },
    {
      id: "ID_TWO",
      value: 2
    }
  ]
};

const normalizedData: NormalizedData = {
  innerData: this.noramlizeInner(rawData.innerData),
};

private noramlizeInner(innerData: InnerData[]): Dict<InnerData> {
  return innerData.reduce((acc:Dict<InnerData>, curr: InnerData) => {
    return {
      ...acc,
      [curr.id]: {
        ...curr
      }
    }
  }, {});
}

但是,如果我更改normalizeInner,我仍然可以编译,并且返回值不正确。

private noramlizeInner(innerData: InnerData[]): Dict<InnerData> {
  return innerData.reduce((acc, curr: InnerData) => {      // changed acc:Dict<InnerData> to acc in the signature.
    return {
      ...acc,
      [curr.id]: [curr]
    }
  }, {});
}

重申问题,我想知道我在reduce函数中做错了什么,为什么它还在编译。

这是用于演示的 CodeSandBox 应用程序 (LINK)。

【问题讨论】:

  • 看起来在reduce()implicit index signatures 中推断的空对象类型{} 之间的交互很差。可能这里的解决方法是指定像innerData.reduce&lt;Dict&lt;InnerData&gt;&gt;(...) 这样的泛型,而不是让它被推断为{}
  • (如this

标签: arrays typescript generics normalization reduce


【解决方案1】:

这里有一个问题,因为您的 Dict 接口接受单个对象作为属性值

interface Dict<T> {
  [key:string]: T;
}

但您尝试分配对象数组

private noramlizeInner(innerData: InnerData[]): Dict<InnerData> {
  return innerData.reduce((acc, curr: InnerData) => {      // changed acc:Dict<InnerData> to acc in the signature.
    return {
      ...acc,
      [curr.id]: [curr]
              // ^ this is array but Dict<InnerData> expects it as single object
    }
  }, {});
}

尝试增强您的 dict 以接受类似这样的对象数组

interface Dict<T> {
  [key: string]: T | T[];
}

或更改您的 reduce 函数以返回对象而不是它们的数组

  private noramlizeInner(innerData: InnerData[]): Dict<InnerData> {
    return innerData.reduce((acc: Dict<InnerData>, curr: InnerData) => {
      return {
        ...acc,
        [curr.id]: curr
      };
    }, {});
  }

【讨论】:

    猜你喜欢
    • 2023-04-03
    • 2011-02-13
    • 2019-09-12
    • 1970-01-01
    • 2019-05-05
    • 2017-06-17
    • 2021-12-23
    • 2021-04-24
    • 2021-05-05
    相关资源
    最近更新 更多