![](/img/trans.png)
[英]Typescript Why type guard does not work as expected for array of objects of type null-able union(strictNullChecks enabled)
[英]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 评论,我还发现了以下内容。
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.