Why does the intersection type for functions accept one of the type expressions not for both?

I gave an example

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

on the documentation page https://flowtype.org/docs/union-intersection-types.html#_

And this type of code 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 follows from the semantics of the semester itself) is a combination of 2 (or more) types. Mostly AND of them.

So why f(new Foo()); doesn't cancel type checking? The new Foo() argument is clearly not an instance of Bar , so it should not pass.

What am I missing?

UPD

After several more studies, I found that the value of | and & swaps when you use declare var (compared to type or in place). I can’t find an explanation why this happens even in the very first place.

+5
source share
1 answer

Perhaps I do not understand your question, but I would expect it to be checked on typecheck. The new Foo() argument is of type Foo , so the application should be fine if f is of type Foo => ... It does. (It also has type Bar => ... ).

For comparison, if f was of type (x: Foo & Bar) => void , things would not be checked by typecheck, because new Foo , although definitely of type Foo , is also not of type Bar .

For another comparison, if f was of type ((x: Foo) => void) | ((x: Bar) => void) ((x: Foo) => void) | ((x: Bar) => void) , things would not be checked. The new Foo argument is of type Foo , and although f may be of type Foo => void , it may be of type Bar => void .

+2
source

Source: https://habr.com/ru/post/1263165/


All Articles