Filter a union of object types down to the members that have a given key. No recursion, no infer: the whole difficulty is understanding distribution.
UnionToObjectFromKey<Union, Key> takes a union of object types and a key name, and returns the member(s) that actually have that key. The solution is compact, but it hinges on two mechanics you'll use constantly in advanced TypeScript: distributive conditional types and per-member keyof checks. The same distribute-and-filter idea underlies how TypeScript narrows discriminated unions.
For example
type Foo = { foo: string; common: boolean }
type Bar = { bar: number; common: boolean }
type Result = UnionToObjectFromKey<Foo | Bar, 'foo'> // expected to be FooFind the object containing the key in the union type by the key. It takes two parameters: a union of object types and a key name.
View on GitHub: https://tsch.js.org/33763
Change the following code to make the test cases pass (no type check errors).
π Lifetime-License is leaving on August 10, 2026
Get it now for $29
One-time payment. Lifetime access to all pro challenges.
Everything fits in two nested conditionals:
type UnionToObjectFromKey<Union, Key> = Union extends unknown
? Key extends keyof Union
? Union
: never
: neverEach conditional has a distinct job.
The outer check Union extends unknown is always true, since every type extends unknown, so it never filters anything. Its only purpose is to trigger distribution: when the type before extends is a bare generic parameter and it's instantiated with a union, TypeScript evaluates the conditional once per member and unions the results.
So for Union = Foo | Bar, the type expands to:
// (Key extends keyof Foo ? Foo : never)
// | (Key extends keyof Bar ? Bar : never)Without this wrapper, keyof Union inside would mean keys shared by all members (keyof (Foo | Bar) is only 'common'), and you could never match a key that exists on just one member. Distribution gives you each member's own keyof instead.
Inside the distributed branch, Union refers to a single member at a time. Key extends keyof Union asks: is Key one of this member's keys?
UnionToObjectFromKey<Foo | Bar, 'foo'>: 'foo' extends keyof Foo is true, so the Foo branch yields Foo; 'foo' extends keyof Bar is false, so the Bar branch yields never.Foo | never. Here the second mechanic kicks in: never is the identity element of unions, so it vanishes. The final answer is Foo.This "return the member or never, let never disappear" idiom is how the built-in Extract and Exclude utilities work under the hood. You've effectively written a custom Extract that filters by key presence instead of assignability.
UnionToObjectFromKey<Foo | Bar, 'foo'> β only Foo has a foo key β Foo.UnionToObjectFromKey<Foo | Bar, 'common'> β both members have common, so both survive and the result stays a union: Foo | Bar. Nothing in the solution forces a single winner; "all members that match" is the correct semantic.UnionToObjectFromKey<Foo | Bar | Other, 'common'> β the tests define Other as { other: string }, so it has no common key, collapses to never and drops out, leaving Foo | Bar. This is the test that proves filtering really happens member by member.There's no recursion and no infer here; the difficulty is conceptual. You need to know that a no-op conditional like Union extends unknown exists purely to switch on distribution, and that keyof behaves very differently on a whole union than on its members. Add the fact that never drops out of unions, and the solution almost writes itself. You'll spot the pattern in plenty of real-world types that pick a variant out of a discriminated union.
This challenge is originally from here.