I took the example
/* @flow */
class Foo {}
class Bar {}
declare var f: ((x: Foo) => void) & ((x: Bar) => void);
f(new Foo());
from the documentation page https://flowtype.org/docs/union-intersection-types.html#_
And this code type checks without errors.
For me the result is not immediately obvious.
As they show somewhere near the top of the page with another example:
/* @flow */
type I = {a: number} & {b: number};
var x: I = {a: 1, b: 2};
x = {a: 1, b: 2, c: "three"};
the intersection (which flows from the term semantics itself) is the compound of 2 (or more) types. Basically AND of those.
So, why does the f(new Foo()); not fail the type check then? The new Foo() argument is clearly not an instance of the Bar so must not pass.
What am I missing?
UPD
After some more research I have found that the meaning of | and & swaps when you use declare var (versus type or in-place typing). I cannot find an explanation why it even happens in the very first place though.
I may be misunderstanding your question, but I would expect it to typecheck. The argument, new Foo(), has type Foo, so the application should be ok as long as f has type Foo => .... It does. (It also has type Bar => ...).
For comparison, if f had type (x: Foo & Bar) => void, things wouldn't typecheck, because new Foo, while certainly of type Foo, is not also of type Bar.
For another comparison, if f had type ((x: Foo) => void) | ((x: Bar) => void), things wouldn't typecheck. The argument, new Foo, has type Foo, and although f might have type Foo => void, it might instead have type Bar => void.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With