【问题标题】:Why does intersection type for functions accept either of type declarations not both?为什么函数的交集类型接受任何类型声明而不接受两者?
【发布时间】:2017-01-23 07:27:58
【问题描述】:

我举个例子

/* @flow */
class Foo {}
class Bar {}
declare var f: ((x: Foo) => void) & ((x: Bar) => void);
f(new Foo());

来自文档页面https://flowtype.org/docs/union-intersection-types.html#_

并且这种代码类型检查没有错误。

对我来说,结果并不是很明显。

当它们显示在页面顶部附近的某个位置时,还有另一个示例:

/* @flow */
type I = {a: number} & {b: number};
var x: I = {a: 1, b: 2};
x = {a: 1, b: 2, c: "three"};

交集(源自术语语义本身)是 2 种(或更多)类型的复合体。基本上是AND

那么,为什么f(new Foo()); 没有通过类型检查呢? new Foo() 参数显然不是 Bar 的实例,因此不能通过。

我错过了什么?

UPD

经过更多研究,我发现|& 的含义在您使用declare var 时互换(相对于type 或就地输入)。不过,我找不到解释为什么它甚至首先发生。

【问题讨论】:

    标签: javascript flowtype


    【解决方案1】:

    我可能误解了您的问题,但我希望它会进行类型检查。参数new Foo() 的类型为Foo,因此只要f 的类型为Foo => ...,应用程序就应该没问题。确实如此。 (它Bar => ...类型)。

    为了比较,如果f 具有(x: Foo & Bar) => void 类型,则不会进行类型检查,因为new Foo 虽然肯定属于Foo 类型,但也不属于Bar 类型。

    对于另一个比较,如果 f 具有类型 ((x: Foo) => void) | ((x: Bar) => void),则不会进行类型检查。参数new Foo 的类型为Foo,虽然f 的类型可能为Foo => void,但它可能改为Bar => void 的类型。

    【讨论】:

    • 我只想引用文档:“交集类型需要一个值为所有输入类型的值:”。在本例中,参数不满足这一点,因为 f(new Foo()); 不是 ((x: Bar) => void) 类型。
    • 另一个有争议的例子:declare vardeclare type 行为不同:flowtype.org/try/…
    • 嗯,我不太明白:(x: Bar) => void 类型是用于 f 本身,而不是 f(new Foo())。我们说f 函数既属于(x: Foo) => void 类型,也属于(x: Bar) => void 类型;因此,可以在 Foo 类型的参数上调用它。
    • 在您的尝试流程示例中,问题是您说a 的类型为F = ((x: Foo) => void) & ((x: Bar) => void),但事实并非如此!它只有(x: Foo) => void 类型。但是,如果将a 的定义更改为function(x: Foo | Bar),它将再次进行类型检查。
    • 现在我明白你的意思了,但这对我来说仍然是反直觉的:-S
    猜你喜欢
    • 1970-01-01
    • 2022-11-16
    • 2016-01-01
    • 1970-01-01
    • 2018-02-19
    • 1970-01-01
    • 2013-01-13
    • 2021-10-11
    • 1970-01-01
    相关资源
    最近更新 更多