Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Typescript: Extract from discriminated union with multiple identical types

I have a type like below:

type Entity =
  | {
      type: 'user' | 'person';
      id: string;
    }
  | {
      type: 'animal';
      id: number;
    };

Now I want to extract the types from it:

type Animal = Extract<Entity, {type: 'animal'}> – works perfectly (returns { type: 'animal'; id: number; });

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

type User = Extract<Entity, {type: 'user'}> – returns never.

How can I make it return { type: 'user'; id: string; }
?

>Solution :

The provided documenation for Extract<T, U> says:

Extract from T those types that are assignable to U

And { type: 'user' | 'person', id: string } is not assignable to { type: 'user' }

declare const entity: Entity
const user: { type: 'user' } = entity
/*
Type 'Entity' is not assignable to type '{ type: "user"; }'.
  Type '{ type: "user" | "person"; id: string; }' is not assignable to type '{ type: "user"; }'.
    Types of property 'type' are incompatible.
      Type '"user" | "person"' is not assignable to type '"user"'.
        Type '"person"' is not assignable to type '"user"'.(2322)
*/

Which means you cannot use Extract to do this.


But what you can do is use an intersection (&), which will trim away any union members that cannot be matched by that discriminant.

type User = Entity & { type: 'user' }

const user: User = { type: 'user', id: 'abc' }
user.id // type: string

See Playground

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading