Saltar al contenido
webtype.org#215 deep-readonly · par 4

N.º 215 · 23 de julio de 2026 · Difícil

Solo lectura profundo

Implementa `DeepReadonly<T>` para que cada propiedad, a cualquier profundidad, sea `readonly`. Las funciones deben pasar intactas.

01

Intenta el puzle tú mismo

Par 4

Puzle

deep-readonly.ts
Intento 1 de 4Aún sin comprobar

Sustituye ??? — tu solución se comprueba con los casos de abajo.

Comprobaciones

4
  • DeepReadonly<{ a: number }>
    { readonly a: number }
  • DeepReadonly<{ a: { b: string } }>
    { readonly a: { readonly b: string } }
  • DeepReadonly<string>
    string
  • DeepReadonly<{ f: () => void }>
    { readonly f: () => void }

Cómo se juzga una comprobación Igualdad exacta de tipos, no asignabilidad — una intersección no es lo mismo que el objeto aplanado.

Cómo le fue a todo el mundo

Nobody is counting yet. Score distribution and the juego corto board arrive with accounts — until then your results stay on this device.

Archivo
02

Solución comentada

Publicado el 24 de julio de 2026

La solución

type DeepReadonly<T> = T extends (...args: never[]) => unknown
  ? T
  : T extends object
    ? { readonly [K in keyof T]: DeepReadonly<T[K]> }
    : T

El error más común

type DeepReadonly<T> = T extends object
  ? { readonly [K in keyof T]: DeepReadonly<T[K]> }
  : T

Sin la guarda para funciones, `() => void` encaja en `extends object` y se mapea. Un tipo función no tiene propiedades enumerables propias, así que el resultado es `{}` — se pierde la firma invocable.

Línea por línea

  1. T extends (...args: never[]) => unknown

    `never[]` en posición de parámetro acepta cualquier firma porque los parámetros se comprueban de forma contravariante. Es la manera segura de decir «cualquier función» sin recurrir a `any`.

  2. { readonly [K in keyof T]: DeepReadonly<T[K]> }

    El modificador `readonly` se añade durante el mapeo y el tipo del valor recurre. Un solo tipo mapeado hace ambas cosas.

Para recordar

Las ramas condicionales se prueban en orden, así que los casos más estrechos van primero. `extends object` es más amplio de lo que casi todo el mundo espera — arrays y funciones lo cumplen.