繁体   English   中英

Typescript 联合类型数组`a[] | b[]` 不是 `reduce`able,而是 `map`able

[英]Typescript union type array `a[] | b[]` is not `reduce`able, but `map`able

我正在尝试reduce数组类型的联合: foo[] | bar[] foo[] | bar[] 使用map它可以按预期工作,并且我在 lamda 中获得了foo|bar的元素,但它不适用于reduce 我收到错误消息,即“表达式不可调用,因为签名不兼容”。

也许是相关的,但那是在 TS 3.6 天,我使用的是 4.5。 有没有解决这个问题的(整洁的)方法?

这里有一个 Typescript 游乐场

const m = [] as Array<number | string>;
m.reduce((it) => it); // ok
m.map((it) => it); // ok

const m2 = [] as Array<number> | Array<string>;
m2.reduce((it) => it);
m2.reduce((it) => it as any);  // not even with 'any'-lambda
// This expression is not callable.
// Each member of the union type '<OMITTED> ...' has signatures, but none of those signatures are compatible with each other.
m2.map((it) => it); // why does `map` work then ?

// same with tuples
const m3 = [1, 1] as [number, number] | [string];
m3.map((it) => it);
m3.reduce((it) => it); // same error

除了 jcalz 评论,我还发现了以下内容。

Typescript 定义

map 的 function 签名是

export function map<T, U>(iterable: Iterable<T>, mapper: (value: T, index: number, iterable: Iterable<T>) => U): U[];

它具有不同的返回类型 U,然后是输入 T。

用于减少的 function 签名之一

export function reduce<T>(
   iterable: Iterable<T>,
    reducer: (previousValue: T, currentValue: T, currentIndex: number, iterable: Iterable<T>) => T,
initialValue?: T
): T;

它具有与输入 (T) 相同的返回类型。 当将类型重新分配给自身时,麻烦就来了。 Typescript 不(也不应该)知道使用哪种类型。

一种解决方案是在使用 reduce 之前进行类型检查,使用这样的类型保护,

const isNumberArray = (arr: unknown[]): arr is number[] => {
  for (let i = 0; i < arr.length; i++) {
      const element = arr[i]

      if (typeof element !== 'number') {
          return false
      }
  }

  return true
}

操场

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM