Solución comentada
Publicado el 4 de septiembre de 2026La solución
type DeepPartial<T> = { [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K] }
El error más común
type DeepPartial<T> = { [K in keyof T]?: T[K] }
Eso es `Partial`, y se detiene en el primer nivel. `{ a: { b: string } }` se convierte en `{ a?: { b: string } }` — la clave externa es opcional y `b` sigue siendo tan obligatoria como antes. La profundidad no sale gratis; el tipo tiene que pedirla.
Línea por línea
T[K] extends object ? DeepPartial<T[K]> : T[K]La recursión vive en la cláusula de valor. Todo lo que tenga forma de objeto vuelve a pasar por `DeepPartial`; los primitivos se devuelven intactos, y eso es lo que termina el descenso.
[K in keyof T]?:El `?` se aplica en todos los niveles porque cada nivel es una nueva llamada al mismo tipo mapeado. Una regla, escrita una vez, aplicada hasta el fondo.
Para recordar
Un tipo mapeado recursivo no es más que un tipo mapeado que se llama a sí mismo en la posición del valor. La condición que lo detiene — aquí, «¿sigue siendo un objeto?» — importa más que la recursión misma.
