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