寻找一个了解静态类型检查器流程的人员来向我解释我在这里转错了哪里。我试图了解子类型函数的交集。
我知道对函数进行子类型化需要输入变量和协变量,但是看来这并不能解决所有问题。
例如
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 | string
和number <: number | string
,对吗?
答案 0 :(得分:0)
Flow中的交叉点类型似乎“严重损坏”(https://github.com/facebook/flow/issues/6482#issuecomment-421167167)。我无法说出test6
和test7
为何失败,但我想指出类型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!
我们观察到number
和string
都不能满足number & string
。因此,老实说,我不知道为什么test1
和test2
会满足类型(number & string) => number | string
。我希望对交点类型在Flow中的工作方式(或应该如何使用)进行澄清。但就目前而言,由于它们的损坏特性,似乎不适合使用。