sindresorhus / type-fest

A collection of essential TypeScript types
Creative Commons Zero v1.0 Universal
14k stars 531 forks source link

Proposal: DiscriminateUnion #528

Open kerwanp opened 1 year ago

kerwanp commented 1 year ago

Proposal

Adding a utility type for discriminated unions to select specific types using discriminator value.

Example:

export type DiscriminateUnion<T, K extends keyof T, V extends T[K]> = 
T extends Record<K, V> ? T : never

export type T1 = { type: 'title', data: string } | { type: 'email', data: string } | { type: 'number', data: number } | { type: 'file': data: { url: string }}

// T2 is "{ type: 'title', data: string }"
export type T2 = DiscriminateUnion<T1, 'type', 'title'>

// T3 is "{ type: 'file': data: { url: string }"
export type T3 = DiscriminateUnion<T1, 'type', 'file'>

// T4 is "{ type: 'title', data: string } | { type: 'email', data: string }"
export type T4 = DiscriminateUnion<T1, 'type', 'title' | 'number''>

Upvote & Fund

Fund with Polar

papb commented 1 year ago

What would be the advantages over doing & { type: 'title' } (or & { type: 'title' | 'number' } on the desired type?

vladshcherbin commented 1 month ago

This can be done in plain typescript:

type T2 = Extract<T1, { 'type': 'title' }>
type T3 = Extract<T1, { 'type': 'file' }>
type T4 = Extract<T1, { 'type': 'title' | 'file' }>