Skip to content

Constrain consistent discriminating union type usage #44788

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

Closed
alexeyMohnatkin opened this issue Jun 28, 2021 · 2 comments
Closed

Constrain consistent discriminating union type usage #44788

alexeyMohnatkin opened this issue Jun 28, 2021 · 2 comments

Comments

@alexeyMohnatkin
Copy link

Bug Report

When I use discriminating unions I expect that only one of them will be allowed by TS, not their intersection

🔎 Search Terms

Discriminating union

🕗 Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about union types

⏯ Playground Link

Playground link with relevant code

💻 Code

type Common = {foo: string};
type A = Common & {a: string};
type B = Common & {b: string};
type Params = Common | A | B;

// expect error here
const bar: Params = {foo: '123', a: '123', b: '123'};

const myFn = (params: Params) => {}

// expect error here
myFn({foo: '123', a: '123', b: '123'})

🙁 Actual behavior

TS allows using both fields from A and B types

🙂 Expected behavior

TS should treat this as an error

Also if I try to set never for fields that I don't want to be set, it doesn't work

type A = Common & {a: string, b: never};
type B = Common & {a: never, b: string};

There's a workaround for this, but it looks hacky

type A = Common & {a: string, b?: never};
type B = Common & {a: never, b: string};
@MartinJohns
Copy link
Contributor

MartinJohns commented Jun 28, 2021

Duplicate of #20863. And you also want #12936.

Additional properties is simply something you have to expect and deal with if you want to write robust code, given the current design of the language.

@alexeyMohnatkin
Copy link
Author

@MartinJohns thank you.

For those who are looking for an answer:

type Common = {foo: string};
type A = {a: string, b?: never};
type B = {a?: never, b: string};
type C = {a?: never, b?: never};
type Params = Common & ( A | B | C);

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

No branches or pull requests

2 participants