Skip to content
Turn a union into a lookup map

    ↑↓ move · ⏎ open · esc close

    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

    1. 01
      [Member in Union

      Mapped types can iterate a union of objects, not only a union of property keys.

    2. 02
      as Member['kind']

      Key remapping promotes each discriminant value to a property name.

    What you get

    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.

    See also

    Patterns