为什么打字稿会针对两个对象类型数组引发错误,但不会同时出现两种形状?

时间:2018-11-10 17:16:12

标签: javascript arrays typescript javascript-objects

我有两种简单的数据类型:

type IData = {
  percent: string;
  exchange: string;
};

type IRow = {
  price: number;
  exchange: string;
};

我没有遵循为什么打字稿如果同时使用它们会在这里引发错误:

const sumSame = (
  assets: IData[] | IRow[],
  sumBy: string,
  sumWhat: string
) => {
  const mapWithUniqCoins = assets.reduce((accMap, el: IData | IRow) => {
    if (accMap.has(el[sumBy])) {
      accMap.set(el[sumBy], {
        ...accMap.get(el[sumBy]),
        [sumWhat]: accMap.get(el[sumBy])[sumWhat] =
          +accMap.get(el[sumBy])[sumWhat] + parseFloat(el[sumWhat])
      });
    } else {
      accMap.set(el[sumBy], el);
    }

    return accMap;
  }, new Map());

  return [...mapWithUniqCoins.values()];
};

但是当我将两种类型组合成一种形状时,它不会引发错误:

type Shape = IData | IRow;

为什么会这样? https://codesandbox.io/s/16vzvqqv3(检查Errors.ts和NoErrors.ts)

1 个答案:

答案 0 :(得分:1)

assets声明为数组的并集

assets: IData[] | IRow[]

assets.reduce()在每种数组类型中都有不同的声明:对于IData[]数组,reduce()进行回调,该回调接收IData元素,对于IRow[]数组,{ {1}}进行了回调,该回调接收了reduce()元素。

错误消息“无法调用其类型缺少调用签名的表达式”-基本上表明编译器不够聪明,无法识别甚至可以为联合类型调用IRow当它收到适当的回调类型时。

There is open issue for this

  

这目前是设计使然,因为我们不合成   获取联合类型的成员时的交叉呼叫签名   -只有相同的呼叫签名才会出现在联合类型上