Given the type:
type Invitation =
| {
__typename?: 'ClientInvitation'
email: string
hash: string
organizationName: string
}
| {
__typename?: 'ExpertInvitation'
email: string
hash: string
expertName: string
}
how can I infer one of the types?
For example:
type ClientInvitation = SomeTypeUtil['ClientInvitation']
should make ClientInvitation
have:
{
__typename?: 'ClientInvitation'
email: string
hash: string
organizationName: string
}
CodePudding user response:
The easiest way to do this is probably to use a mapped type with renamed keys like this:
type InvitationMap = { [T in Invitation as NonNullable<T['__typename']>]: T }
Here we are iterating the type T
over the union members of Invitation
. For each such member T
we want the property value to be T
, and we want the property key to be the string literal type of T
's __typename
property. That would just be T['__typename']
using indexed access, but that doesn't quite work. Because the __typename
property is optional, the property type will include undefined
(like 'ClientInvitation' | undefined
or 'ExpertInvitation' | undefined
). To remove undefined
quickly we can use the NonNullable<T>
utility type.
Let's look at the IntelliSense quick info for the InvitationMap
type:
/* type InvitationMap = {
ClientInvitation: {
__typename?: "ClientInvitation" | undefined;
email: string;
hash: string;
organizationName: string;
};
ExpertInvitation: {
__typename?: "ExpertInvitation" | undefined;
email: string;
hash: string;
expertName: string;
};
} */
Now that we have InvitationMap
, we can just index into it with the desired key:
type ClientInvitation = InvitationMap['ClientInvitation'];
/* type ClientInvitation = {
__typename?: "ClientInvitation" | undefined;
email: string;
hash: string;
organizationName: string;
} */