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

Disallow intersection of exact objects #8158

Open
villesau opened this issue Oct 26, 2019 · 3 comments
Open

Disallow intersection of exact objects #8158

villesau opened this issue Oct 26, 2019 · 3 comments

Comments

@villesau
Copy link
Contributor

villesau commented Oct 26, 2019

Proposal

Intersections of exact objects does not make sense since they produce impossible type that can't be used. {| a: number|} & {| b: string |}produces an object type that only has property a and nothing else, but also has property b and nothing else. This indicates that intersections can only be used for inexact objects.

In optimal case the error message would be describing and maybe communicate why intersection of exact objects can't be used and suggest to use spreading instead.

This is important especially for newcomers and people who are used to write TS. I find my self very often explaining how and why intersection of exact objects can't be used.

I understand that this might not be big deal for FB, but for community it's important to make experience good for newcomers.

@villesau villesau changed the title Disallow union of exact objects Disallow intersectionn of exact objects Oct 26, 2019
@villesau villesau changed the title Disallow intersectionn of exact objects Disallow intersection of exact objects Oct 26, 2019
@SillyFreak
Copy link

There are corner cases where the intersection type is not empty:

type A = {|
  foo: number | string,
|};

type B = {|
  foo: bool | string,
|};

let x: $ReadOnly<A&B> = { foo: 'a', };

or

type A = {|
  a?: number,
  c: number,
|};

type B = {|
  b?: number,
  c: number,
|};

let x: $ReadOnly<A&B> = { c: 0, };

($ReadOnly prevents adding properties to x that would make the object no longer conform to its intersection type)

But I agree that warning against empty intersections of exact types would be useful in most cases and to a lot of people.

@villesau
Copy link
Contributor Author

@SillyFreak Interesting, hadn't thought about those cases! Anyhow, do you think there would be any real world use cases with them that couldn't be achieved easily in other ways?

@SillyFreak
Copy link

real world use cases I'm not sure, but disallowing intersection types in this specific circumstance, because there are workarounds for when this is actually the desired behavior seems like the wrong approach. Maybe a lint would make sense, but disallowing this seems too harsh.

In principle it should be possible to determine when the resulting type is empty, and disallowing such types (including number & string) would IMO make more sense than the "heuristic" of exact object intersections. But even then, empty types are not entirely useless. Take this function:

function throws(): void { throw new Error(); }

void is not the most specific type that I could use here: void's only value is undefined, but this function never returns undefined. I could specify number & string as well.

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

2 participants