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