1

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
    }
2
  • 1
    Do you really mean to use brackets (indexed access) like SomeTypeUtil['ClientInvitation']? Or would a normal generic type utility like SomeTypeUtil<'ClientInvitation'> be acceptable? You can actually do it either way, but it's a little weird to expect that indexed access would be possible. Is this just a typo? Commented Mar 15, 2022 at 15:28
  • @jcalz I don't really care :) Do you want to convert your comment to an answer? Commented Mar 15, 2022 at 15:57

1 Answer 1

1

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;
} */

Playground link to code

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.