TypeScript,如何通过泛型正确使用Array.prototype.reduce

问题描述 投票:0回答:1

我正在尝试使用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)供演示。

arrays typescript generics normalization reduce
1个回答
0
投票

这里有问题,因为您的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
    }
  }, {});
}

尝试增强您的字典以接受对象数组,也像这样

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
      };
    }, {});
  }
© www.soinside.com 2019 - 2024. All rights reserved.