Patterns
How do I index a discriminated union by its `kind` instead of repeatedly extracting members?
Map over the union and remap each member to the literal value of its discriminant.
The recipe
type ByKind<Union extends { kind: PropertyKey }> = { [Member in Union as Member['kind']]: Member } type Action = | { kind: 'add'; amount: number } | { kind: 'reset' } | { kind: 'rename'; name: string } type ActionMap = ByKind<Action>
The build compiles this and checks each result below.
How it works
- 01
[Member in UnionMapped types can iterate a union of objects, not only a union of property keys.
- 02
as Member['kind']
Key remapping promotes each discriminant value to a property name.
What you get
ActionMap['add']→{ kind: "add"; amount: number; }ActionMap['reset']→{ kind: "reset"; }keyof ActionMap→"add" | "reset" | "rename"
Where it goes wrong
Every discriminant must be a unique `PropertyKey`. If two members share the same `kind`, their values merge under one property and the lookup no longer identifies a single member.
Takeaway
Key remapping turns a union’s discriminant into an index for constant-time type lookup.
