Javascript 当array.map返回不正确的类型时,忽略';过滤器';
例如:Javascript 当array.map返回不正确的类型时,忽略';过滤器';,javascript,flowtype,Javascript,Flowtype,例如: let foo: number[]; foo = [1, 2, 3] .map(number => number === 1 ? number : null) .filter(number => number); 我得到一个错误: 8:.映射(编号=>编号===1?编号:空) ^无法将[…].map(…).filter(…)分配给foo,因为null不兼容 数组元素中的数字为[2] (你可以玩它) Flow查看“.map”部分并显示有关类型的错误,因为我有时返回n
let foo: number[];
foo = [1, 2, 3]
.map(number => number === 1 ? number : null)
.filter(number => number);
我得到一个错误:
8:.映射(编号=>编号===1?编号:空)
^无法将[…].map(…).filter(…)
分配给foo
,因为null不兼容
数组元素中的数字为[2]
(你可以玩它)
Flow查看“.map”部分并显示有关类型的错误,因为我有时返回null
,它只需要数字。
但是,它忽略了我使用的“.filter”,它消除了所有null
值
我如何在不使用“$FlowFixMe”的情况下解决它,因为我确实希望得到其他流错误。这是因为您先使用map和将
null
值分配给整数数组,然后过滤它。因此,在您的第一个操作中,map
,将在调用filter
之前抛出一个错误
在这种情况下,您可以直接使用filter
:
let foo: number[];
foo = [1, 2, 3]
.filter(number => number == 1);
当您想映射
+过滤
时,减少
可以简化您的工作:
let foo: number[];
foo = [1, 2, 3]
.reduce((acc, number) => number == 1 ? acc.concat(number + 1) : acc, [])
从其他评论中,我看到这是对实际用例的简化。在您的示例中,map
是多余的,并且具有误导性,您可以简单地使用filter
实现同样的效果,但假设您确实需要该步骤
似乎您希望foo
成为一个数字数组,或者使用null来支持map
操作,然后您希望过滤掉null
您使用的是数组语法的缩写形式(number[]
),如果要将数组元素键入为可选,则不能使用该语法。这将允许您指定null
是允许的值
let foo: Array<?number>;
foo = [1, 2, 3]
.map(number => number === 1 ? number : null)
.filter(number => number);
您的筛选器将number
强制为真实值,这将过滤掉等于零的有效数字(您的示例在这方面可能过于简化)
如果您不想使用数组排列(..
),那么您可以使用memo.push(number)
或memo.concat([number])
,具体取决于您对memo
的易变性的偏好,.filter()
发生在.map()
调用之后。也许可以使用.reduce()
来代替。你想实现什么?@Pointy,我不能使用.reduce()
,因为我想得到一个数组作为结果。@David.reduce()
返回你想要的结果return@Pointy安德烈亚斯,你们说得对。(我只是在代码中快速地将单词filter
替换为reduce
,没有考虑太多)。在上面的示例中,我简化了实际用例。假设您确实需要“.map”返回带有一些计算的结果。下面是一个示例:foo=[1,2,3].map(number=>number==1?number+1:null).filter(number=>number)
我知道它在.filter
之前调用了.map,但是foo
获取值作为.map
和.filter
的最终结果。事实上,您是对的,foo
在map
和filter
的结果之后获取值。我的猜测是flow
不支持checker-to-chained函数。无论如何,你可以像我上面所做的那样使用reduce
。谢谢@guijob,这样可以工作,我不会出错。唯一的问题是,对我来说,它使它不那么可读。因为我的目的不是减少原始阵列。在实际情况中,我在.map
部分进行大量计算,很少返回null
。我希望我能教Flow把“过滤器”考虑在内。
let foo: Array<number | null>;
foo = [1, 2, 3]
.map(number => number === 1 ? number : null)
.filter(number => number);
let foo: Array<number | null>;
foo = [1, 2, 3]
.map(number => number === 1 ? number : null)
.filter(number => typeof number === 'number');
let foo: Array<number | null>;
foo = [1, 2, 3]
.reduce((memo, number) => {
if (number === 1) {
return [ ...memo, number ];
}
return memo;
}, []);