Home > Blockchain >  Extract specific Type from a Record<string, Type> in Typescript
Extract specific Type from a Record<string, Type> in Typescript

Time:10-19

Consider a type PageProps : Record<string, Type>:

type PageProps = Record<
  string,
  | {
      type: "title";
      title: Array<{
        type: "text";
        text: {
          content: string;
          link: {
            url: string;
          } | null;
        };
        plain_text: string;
        href: string | null;
      }>;
    }
  | {
      type: "rich_text";
      rich_text: Array<
        | {
            type: "text";
            text: {
              content: string;
              link: {
                url: string;
              } | null;
            };
            plain_text: string;
            href: string | null;
          }
        | {
            type: "equation";
            equation: {
              expression: string;
            };
            plain_text: string;
            href: string | null;
          }
      >;
      id: string;
    }
  | {
      type: "number";
      number: number;
      id: string;
    }
  | {
      type: "url";
      url: string;
      id: string;
    }
>;

How can I extract below type from the above PageProps : Record<Keys, Type>:

type RichText = {
      type: "rich_text";
      rich_text: Array<
        | {
            type: "text";
            text: {
              content: string;
              link: {
                url: string;
              } | null;
            };
            plain_text: string;
            href: string | null;
          }
        | {
            type: "equation";
            equation: {
              expression: string;
            };
            plain_text: string;
            href: string | null;
          }
      >;
      id: string;
    }

I tried Pick and Extract but couldn't get it to work for Record<Keys, Type>.

Try this in TS Playgroud

Note: PageProps comes from a module so it's not possible to edit/refactor it.

CodePudding user response:

You can get access to this part of the discrimnated union like this:

type RichText = Extract<PageProps[string], {type: "rich_text"}>;

This essentially relies on the fact that PageProps[string] is a discrimnated union and makes use of the fact that TypeScript distributes over union types used as generic type arguments.

  • Related