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

[Proposal] Defining a way to discriminated unions in interfaces #108

Open
j0nl1 opened this issue May 17, 2023 · 2 comments
Open

[Proposal] Defining a way to discriminated unions in interfaces #108

j0nl1 opened this issue May 17, 2023 · 2 comments

Comments

@j0nl1
Copy link

j0nl1 commented May 17, 2023

Currently now when you have an interface or type that use an union, is really hard to access to the desired property.
In the example below you could see how is not possible to access to a specific property from an union (at least you force the type). However defining generics in the root object and make programmers define the expected union is more much friendly programming experience.

image

The generation process could be something like:

  1. Check for Unions in the object, generate as many generic as unions in the root object and start from A to Z.
  2. Generate each type of an union separately.
  3. Do conditional type until check all types in the union.

Follow the same process with Unions that have nested Unions.

You could find a full example here: https://gist.github.com/j0nl1/22dde0ef0bfaf1c0bea870a0a39e039e

@adairrr
Copy link
Contributor

adairrr commented May 21, 2023

@j0nl1 nice suggestion on separating the unions, that would be quite a nice improvement, though I'm not sure about this "flattened" type.

Have you tried using ts-pattern? It works quite well for these unions.

You also can extract the types individually as follows:

Extract<ExecuteMsg, {
    create_wallet: unknown;
  }>["create_wallet"]

@j0nl1
Copy link
Author

j0nl1 commented May 23, 2023

@adairrr thanks for the suggestion of ts-pattern. I think is really useful in case where you don't know what data is coming. In scenarios where you already know what is going to come, it would be really useful to have something like what I proposed.

I think is very annoying have to force the definition of an union type every time you want to interact with that interface.

Given the example below I would have to do something like this:

const response: Interface = method(); 
(response.expires as Extract<Interface, { expires: { never:  {} }  }>).never
// OR
(response.expires as { never: {} }).never

Instead of

const response: ProposalInterface< ExpirationNever> = method(); 
response.expires.never

assuming that method has a return type of ProposalInterface<ExpirationNever> I never would have to cast or to force a type. In the case above is not that annoying because ExpirationNever is a small interface but there are much bigger interfaces and having to define them is repetitive.

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