Skip to content
webtype.orgRequire at least one property

    ↑↓ move · ⏎ open · esc close

    Patterns

    How do I accept an options object where every field is optional, but the empty object is not allowed?

    Build one variant per key where that key is required and the rest are optional, then union them. Any single supplied key satisfies at least one variant.

    The recipe

    type AtLeastOne<T> = {
      [K in keyof T]: Required<Pick<T, K>> & Partial<Omit<T, K>>
    }[keyof T]
    
    type Filters = {
      name?: string
      age?: number
    }
    
    type ValidFilters = AtLeastOne<Filters>

    The build compiles this and checks each result below.

    How it works

    1. 01
      Required<Pick<T, K>> & Partial<Omit<T, K>>

      One variant: this key required, everything else optional. `Required` matters because the source properties were already optional.

    2. 02
      }[keyof T]

      Index the whole table by every key at once, collapsing the variants into a union. The same trick the archive uses to turn a lookup table into an answer.

    What you get

    Where it goes wrong

    The union grows with the number of keys, and error messages grow with it — a ten-key options type produces a ten-member union and a diagnostic nobody will read. Keep it for small option bags.

    Takeaway

    Map to variants, then index by `keyof` to union them. That two-step is the general shape for "one of these, at least".

    See also

    Patterns