typescripttypesbranding

Extract type from branded type


How can I extract the type of a branded type in TypeScript?

It works on non literal brands:

type Branded = string & {
  brand: string;
};

type Extract_I<T> = T extends infer V & { brand: string } ? V : never;

type Result_I = Extract_I<Branded>; // => string

But not for literal brands:

type LiteralBranded = string & {
  brand: 'brand';
};

type Result_II = Extract_I<LiteralBranded>; // =>  string & { brand: "brand" }

How can I make this work?

This is something else I've tried:

type Extract_II<T> = T extends { brand: string } ? T & { brand: never } : never; // does not work.

Solution

  • You need to infer the brand's type first:

    Playground

    type Extract_I<T> = T extends { brand: infer X } ? T extends infer V & { brand: X } ? V : never : never;