ExtractToObject
Less than 1 minuteTC-Medium
ExtractToObject
Problem
Implement a type that extracts the value of a property from a union of objects and merges it with the rest of the object.
type T0 = ExtractToObject<{ id: 1; city: 'New York' } | { id: 2; city: 'Paris' }, 'city'>
// { id: 1; city: 'New York' } | { id: 2; city: 'Paris' } (same here, city is scalar)
// More illustrative:
type T1 = ExtractToObject<
{ id: 1; address: { city: 'New York'; zip: '10001' } } |
{ id: 2; address: { city: 'Paris'; zip: '75001' } },
'address'
>
// { id: 1; city: 'New York'; zip: '10001' } | { id: 2; city: 'Paris'; zip: '75001' }Solution
type ExtractToObject<T, U extends keyof T> =
T extends T
? Omit<T, U> & T[U]
: neverWith flattening:
type Flatten<T> = { [K in keyof T]: T[K] }
type ExtractToObject<T, U extends keyof T> =
T extends T
? Flatten<Omit<T, U> & T[U]>
: neverHow it works:
T extends Tdistributes the operation over each member of the union.- For each union member,
Omit<T, U>removes the keyUfrom the object. T[U]is the type of the extracted property (an object type in the interesting case).- Intersecting with
T[U]merges its properties into the result. Flattencollapses&into a clean object type.
Key Takeaways
- Distribution with
T extends Tapplies the transformation per union member, preserving the union structure. Omit<T, U> & T[U]is the standard "spread/inline nested object" pattern.Flatten<T>({ [K in keyof T]: T[K] }) resolves intersection types into a single readable object type.
