假阳性谓词函数类型检查Flow中返回其参数否定的函数

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

这段代码:

type Predicate = any => boolean;

const xs = [1, 2, 3, 4, 5, 6];
const isEven = (x: number): boolean => x % 2 === 0;
const filter = (pred: Predicate) => (xs: Array<number>) => xs.filter(pred);

filter(isEven)(xs);

被Flow认为是好的。但是这段代码:

type Predicate = any => boolean;

const xs = [1, 2, 3, 4, 5, 6];
const filter = (pred: Predicate) => (xs: Array<number>) => xs.filter(pred);

filter(x => -x)(xs);

也算不错。这很奇怪,因为函数x => -x永远不会返回布尔值。如果我对Predicate中的参数类型更具体,并说它必须是一个数字,比如

type Predicate = number => boolean;

const xs = [1, 2, 3, 4, 5, 6];
const filter = (pred: Predicate) => (xs: Array<number>) => xs.filter(pred);

filter(x => -x)(xs);

然后我得到Flow来显示一些相关的错误,就像它应该:

6: filter(x => -x)(xs);
                ^ Cannot call `filter` with function bound to `pred` because number [1] is incompatible with boolean [2] in the return value.
References:
1: type Predicate = number => boolean;
                    ^ [1]
1: type Predicate = number => boolean;
                              ^ [2]

同时,如果我尝试使该函数返回更突出的类型,Flow会发现问题。 Flow将这些调用正确地视为包含类型错误:

filter(x => String(x))(xs); // <- string is incompatible with boolean, okay
filter(x => Number(x))(xs); // <- number is incompatible with boolean, also okay
filter(x => +x)(xs); // <- +x will always evaluate into a number or NaN, never a boolean
filter(x => x & x)(xs); // <- number is incompatible with boolean

有没有办法对特定情况x => -x进行类型检查并让Flow显示错误?或者在这种情况下Flow是否正确地进行了类型检查,这只是我遗漏了什么?

javascript flowtype
1个回答
1
投票

使用泛型类型可以在这里提供帮助

type Result<T> = Array<T> => Array<T>;

const xs = [1, 2, 3, 4, 5, 6];
const filter = <T>(pred: (T) => boolean): Result<T> => xs => xs.filter(pred);

filter(x => -x)(xs);

试试吧:https://flow.org/try/#0C4TwDgpgBAShDOBXANsAPAFQHxQLxQEEAnIgQxEx1x2LIuwG4AoJgYwHsA7eYKAD3h4oAbQCMAGigAmSQGZJAFkkBWSQDYAusw7deAMwCWqCESGUAFGCIQAJgC4o5jAEo8OAEbt2yCKU7OHOCRUSjd+QWpwgDpDYyJLaxtnZiZY4BNzPjCAWj5nTPhkoA

© www.soinside.com 2019 - 2024. All rights reserved.