Solución comentada
Publicado el 9 de agosto de 2026La solución
type CamelCase<S extends string> = S extends `${infer H}_${infer T}` ? `${H}${CamelCase<Capitalize<T>>}` : S
El error más común
type CamelCase<S extends string> = S extends `${infer H}_${infer T}` ? `${H}${CamelCase<T>}` : S
Se elimina el guion bajo pero no se capitaliza nada, así que `"foo_bar"` queda en `"foobar"`. Quitar el separador es solo la mitad de la transformación — el cambio de mayúscula es la otra mitad.
Línea por línea
Capitalize<T>Uno de los cuatro tipos de cadena intrínsecos que el compilador implementa de forma nativa — `Uppercase`, `Lowercase`, `Capitalize`, `Uncapitalize`. No tienen código TypeScript; están dentro del comprobador.
CamelCase<Capitalize<T>>Capitalizar *antes* de recurrir hace que cada nivel solo tenga que ocuparse del guion bajo más cercano al principio. Por eso `"a_b_c"` da `"aBC"` — la recursión capitaliza cada segmento restante por turno.
Para recordar
Los tipos intrínsecos de mayúsculas hacen la manipulación de cadenas a nivel de tipos mucho menos dolorosa de lo que tendría derecho a ser. Recurre a ellos antes de escribir una recursión carácter a carácter.