Przejdź do treści
webtype.org#226 rebuild-readonly · par 2

Nr 226 · 3 sierpnia 2026 · Łatwa

Odtwórz Readonly

Zaimplementuj `MyReadonly<T>`, aby każda właściwość stała się `readonly`. Tylko jeden poziom — zagnieżdżone obiekty zostają nietknięte.

01

Spróbuj rozwiązać samodzielnie

Par 2

Zagadka

rebuild-readonly.ts
interface Config {
  host: string
  port: number
}
Podejście 1 z 2Jeszcze nie sprawdzone

Zastąp ??? — rozwiązanie sprawdzamy przypadkami poniżej. Tab wcina; naciśnij Escape, a potem Tab, by wyjść fokusem.

Testy

3
  • MyReadonly<Config>
    { readonly host: string; readonly port: number }
  • MyReadonly<{ a: string }>
    { readonly a: string }
  • MyReadonly<{}>
    {}

Jak oceniamy test Dokładna równość typów, nie przypisywalność — przecięcie to nie to samo co spłaszczony obiekt.

Jak poszło innym

Tę zagadkę rozwiązało jak dotąd mniej niż 5 osób. Rozkład pojawi się, gdy próbka będzie na tyle duża, by coś znaczyć.

Archiwum
02

Rozwiązanie z komentarzem

Opublikowano 4 sierpnia 2026

Rozwiązanie

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

Najczęstsza błędna odpowiedź

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

To stosuje `Readonly` do każdej *wartości*, a nie do mapowania. Dla prymitywu takiego jak `string` nie robi to nic, więc klucze pozostają modyfikowalne, a wynik jest po prostu kopią `T`.

Linia po linii

  1. readonly [K in keyof T]

    Modyfikator poprzedza klauzulę klucza, tak jak napisałbyś `readonly host: string` w interfejsie. Oznacza właściwość, a nie typ jej wartości.

  2. T[K]

    Wartość przechodzi nietknięta, co utrzymuje płytkość. Rekurencja w tym miejscu to dokładnie sposób budowy `DeepReadonly`.

Do zapamiętania

Modyfikatory działają na właściwościach; owinięcie typu wartości to zupełnie inna operacja. Pomylenie ich daje typ, który wygląda dobrze i niczego nie egzekwuje.