-
Notifications
You must be signed in to change notification settings - Fork 13k
Closed
Labels
FixedA PR has been merged for this issueA PR has been merged for this issue
Description
I've found it frequently desirable to be able to "look up" the union variant associated with a type tag. For example, given a union
type Foo = { tag: 'n'; val: number } | { tag: 's'; val: string }
one wants to be able to write a type operator
type Lookup<T extends Foo['tag']> = // ???
such that Lookup<'n'>
= number
and Lookup<'s'>
= string
.
I don't think this is possible in the current type system (would welcome correction on that point). Instead, we can use the trick of starting with a Lookup
type, and deriving the union type from it:
type Lookup = {
n: number
s: string
}
type Foo = {
[T in keyof Lookup]: { tag: T; val: Lookup[T] }
}[keyof Lookup]
then the inferred type of Foo
is
type Foo = {
tag: "n";
val: number;
} | {
tag: "s";
val: string;
}
as desired, and we have our lookup type: Lookup['n']
= number
and Lookup['s']
= string
.
So I use this pattern a lot, and I wanted to generalize it:
type Unionize<Lookup> = {
[T in keyof Lookup]: { tag: T; val: Lookup[T] }
}[keyof Lookup]
Unfortunately, this doesn't do what you want:
type Foo = Unionize<{
n: number
s: string
}>
Here, Foo
is inferred to be
type Foo = {
tag: "n" | "s";
val: string | number;
}
This seems like a bug!
jcalz
Metadata
Metadata
Assignees
Labels
FixedA PR has been merged for this issueA PR has been merged for this issue