Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intersection of a union doesn't refine the type as expected #1118

Closed
pasha-mf opened this issue Nov 19, 2015 · 2 comments
Closed

Intersection of a union doesn't refine the type as expected #1118

pasha-mf opened this issue Nov 19, 2015 · 2 comments

Comments

@pasha-mf
Copy link
Contributor

type A = { mode: "a", x: number };
type B = { mode: "b", y: string };
type C = { mode: "b" };
function test(foo: (A|B)&C) {
  (foo.y: string); // doesn't work
}

I would expect Flow to carry out a transform (A|B)&C => (A&C)|(B&C) => {}|B => B, but that's not the case.

@pasha-mf
Copy link
Contributor Author

Not sure if this is the same bug or different, but here's another test case:

class Foo {};
class Bar extends Foo {};
function test(a: Foo & Bar,  b: {foo: Foo} & {foo: Bar}) {
  (a: Bar);     // ok
  (b.foo: Bar); // error
}

@avikchaudhuri
Copy link
Contributor

@pasha-mf These don't seem like bugs to me.

On your first example: A&C is actually not defined (it's not BOTTOM), given that there's no reason to believe mode is read-only: computing the intersection would involve asserting "a" = "b", which is a contradiction. So your simplification doesn't hold. The direct simplification would compute A | B = { }, so (A | B) & C = C which doesn't contain y.

The second example is similar: { foo: Foo } & { foo: Bar } is not defined when Foo and Bar are not the same.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants