了解流程中的函数类型的交集

时间:2019-04-03 02:56:39

标签: javascript facebook flowtype

寻找一个了解静态类型检查器流程的人员来向我解释我在这里转错了哪里。我试图了解子类型函数的交集。

我知道对函数进行子类型化需要输入变量和协变量,但是看来这并不能解决所有问题。

例如

type InterT = ((number) => string) & ((string) => number);

通过简单的测试,看来可以归结为(number & string) => number | string。有效的子类型包括

declare var I: InterT;

declare var test1: ((number) => number | string) => void;
test1(I); // works

declare var test2: ((string) => number | string) => void;
test2(I); // works

declare var test3: ((number & string) => number) => void;
test3(I); // works

declare var test4: ((number & string) => string) => void;
test4(I);

declare var test5: ((number | string) => number | string) => void;
test5(I); // works 

declare var test6: ((number | string) => string) => void;
test6(I); // FAILS 

declare var test7: ((number | string) => number) => void;
test7(I); 

为什么这两种情况都失败了? string <: number | stringnumber <: number | string,对吗?

1 个答案:

答案 0 :(得分:0)

Flow中的交叉点类型似乎“严重损坏”(https://github.com/facebook/flow/issues/6482#issuecomment-421167167)。我无法说出test6test7为何失败,但我想指出类型number & string是“不可能”类型(https://flow.org/en/docs/types/intersections/#toc-impossible-intersection-types)。从文档中:

// @flow
type NumberAndString = number & string;

function method(value: NumberAndString) {
  // ...
}

// $ExpectError
method(3.14); // Error!
// $ExpectError
method('hi'); // Error!

我们观察到numberstring都不能满足number & string。因此,老实说,我不知道为什么test1test2会满足类型(number & string) => number | string。我希望对交点类型在Flow中的工作方式(或应该如何使用)进行澄清。但就目前而言,由于它们的损坏特性,似乎不适合使用。