-
Notifications
You must be signed in to change notification settings - Fork 327
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
New Feature: add TaggedUnionType #183
Conversation
@gcanti that would be a great addition. As for the usage of the lib, we found out that to ease with developper experience, see this: pelotom/unionize#35 P.S.: 'Extract' with 'union's is quite a powerful tool :) |
@sledorze sorry, I'm not sure what should I look at.
const x = constructors.A({ foo: 'foo' })
// x has type C as expected |
@gcanti I m AFK so i ve not tried it. |
Yes const x = taggedConstructors.A({ foo: 'foo' })
/* x has type
t.TypeOfProps<{
tag: t.LiteralType<"A">;
foo: t.StringType;
}> | t.TypeOfProps<{
tag: t.LiteralType<"B">;
bar: t.NumberType;
baz: t.BooleanType;
}>
as expected
*/ You can get a neater result if you use const AR_ = t.type({
tag: t.literal('A'),
foo: t.string
})
interface AR extends t.TypeOf<typeof AR_> {}
const AR = t.alias(AR_)<AR, AR>()
const BR_ = t.type({
tag: t.literal('B'),
bar: t.number,
baz: t.boolean
})
interface BR extends t.TypeOf<typeof BR_> {}
const BR = t.alias(BR_)<BR, BR>()
const CR = t.taggedUnion('tag', [AR, BR])
const x = taggedConstructors.A({ foo: 'foo' })
// x has type AR | BR as expected |
that would nice to be able to call this would be a great addition |
To come back to that matter, we use unionize on the front side but a custom variation of it in the back-end as we have two tags per Commands/Events (CQRS backend). The impact of that (double) tags is that, for instance, @gcanti I'm not saying that you should stick to that requirement, it's just feedback from the trenches. |
@gcanti Does this approach support renaming of tags, like in unionize? I.e. will TypeScript persist a rename of a tag to the type definition and all of its usages? (I ask because I've ran into problems before where this doesn't always happen.) |
@OliverJAsh not sure what you mean, however you can find out by yourself: I just put up a branch ( |
Thanks @gcanti. I just tried it. Unfortunately renaming tags doesn't persist. What I mean by this is if you try to rename the tag in This is the behaviour I currently rely on in unionize. Before: … and after: |
@gunzip I'm not going to add anything related to constructors / pattern matching to io-ts (*), however if somebody is willing to publish a library containing @OliverJAsh I see, thanks. Looks like it's something related to the refactoring features of TypeScript, not sure we can do anything about it. (*) Personally I think that custom constructors and |
@gcanti beware, nested switch in typescript have(had?) an inference issue, loosing some refinements. |
@gcanti Are you thinking of merging this or is it on hold? |
40c01f1
to
00639c3
Compare
@OliverJAsh released |
@gcanti Do you have any intention to publish your helpers in a separate library? |
@OliverJAsh No, I don't
feel free to take/modify/extend my snippets above |
@gcanti Are your snippets here in this PR your most recent/refined attempts? I saw some places where you had others. Just wondering. |
@joshburgess yes they are, off the top of my head the only thing that I would change is -export type TagValue<A, Tag extends keyof A> = A[Tag] & (string | number)
+export type TagValue<A, Tag extends keyof A> = A[Tag] & PropertyKey |
@sledorze I know you are using
unionize
in order to handle ADTs so I'd like to hear your opinion on this: I'm trying to define some helper functions for tagged unions (and maybe a small library). This is the general form (works with any tagged union)Usage
I also wrote a version which leverages
io-ts
tagged unions (note that I need this PR since I'm usingT['tag']
in the implementations)Usage