Skip to content
webtype.orgwebtype.org#241 rebuild-required · par 2

    ↑↓ move · ⏎ open · esc close

    No. 241 · August 24, 2026 · Gentle

    Rebuild Required

    Implement `MyRequired<T>` so every optional property becomes required. This is the exact inverse of puzzle #219.

    01

    Try the puzzle yourself

    Par 2

    Puzzle

    rebuild-required.ts
    interface Draft {
      title?: string
      body?: string
    }
    Stroke 1 of 2Not run yet

    Replace ??? — your solution is checked against the cases below. Tab indents; press Escape then Tab to move focus out.

    Checks

    3
    • MyRequired<Draft>
      { title: string; body: string }
    • MyRequired<{ a?: number }>
      { a: number }
    • MyRequired<{ a: string }>
      { a: string }

    How a check is judged Exact type equality, not assignability — an intersection is not the same as the flattened object.

    How everyone did

    Fewer than 5 people have solved this one so far. The distribution appears once there is enough of a sample to mean anything.

    Short game

    Fewest characters

    No public scores yet.

    Archive
    02

    Annotated solution

    Published August 25, 2026

    The solution

    type MyRequired<T> = { [K in keyof T]-?: T[K] }

    The common wrong answer

    type MyRequired<T> = { [K in keyof T]: T[K] }

    This is the identity mapping, and that is the surprise: a mapped type over `keyof T` is *homomorphic*, so it copies the existing `?` and `readonly` modifiers across rather than dropping them. Optional properties stay optional, and the type is unchanged.

    Line by line

    1. -?

      The minus subtracts the modifier. It does two things at once: the key stops being optional, and `undefined` is removed from the value type — which is why `title?: string` becomes `title: string` and not `title: string | undefined`.

    2. { [K in keyof T]

      Mapping directly over `keyof T` is what makes this homomorphic, and homomorphic is what makes modifiers inheritable in the first place. Map over a computed key set instead and every modifier is lost by default.

    Takeaway

    `+` and `-` before `?` or `readonly` are the only way to change a property’s modifiers. Without them a mapped type quietly preserves whatever was already there, which makes "nothing happened" a very common bug.

    Uses