Skip to content
webtype.orgwebtype.org#226 rebuild-readonly · par 2

    ↑↓ move · ⏎ open · esc close

    No. 226 · August 3, 2026 · Gentle

    Rebuild Readonly

    Implement `MyReadonly<T>` so every property becomes `readonly`. One level only — nested objects are left alone.

    01

    Try the puzzle yourself

    Par 2

    Puzzle

    rebuild-readonly.ts
    interface Config {
      host: string
      port: number
    }
    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
    • MyReadonly<Config>
      { readonly host: string; readonly port: number }
    • MyReadonly<{ a: string }>
      { readonly a: string }
    • MyReadonly<{}>
      {}

    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 4, 2026

    The solution

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

    The common wrong answer

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

    This applies `Readonly` to each *value* instead of to the mapping. For a primitive like `string` that does nothing at all, so the keys stay mutable and the result is just a copy of `T`.

    Line by line

    1. readonly [K in keyof T]

      The modifier precedes the key clause, mirroring how you would write `readonly host: string` in an interface. It marks the property, not the type of its value.

    2. T[K]

      The value passes through untouched, which is what keeps this shallow. Recursing here instead is exactly how `DeepReadonly` is built.

    Takeaway

    Modifiers act on properties; wrapping the value type is a different operation entirely. Confusing the two produces a type that looks right and enforces nothing.

    Uses