type KebabCase<S extendsstring> =
S extends`${infer H}${infer R}`
? R extends Uncapitalize<R>
? `${Lowercase<H>}${KebabCase<R>}`
: `${Lowercase<H>}-${KebabCase<R>}`
: S
El error más común
type KebabCase<S extendsstring> = Lowercase<S>
`Lowercase` cambia las letras pero olvida dónde estaban los límites de palabra. Cuando desaparecen las mayúsculas ya no queda información para insertar los guiones.
Línea por línea
R extends Uncapitalize<R>
El sufijo empieza en minúscula cuando `Uncapitalize` no lo cambia. Si lo cambia, su primer carácter marca una palabra nueva.
Para recordar
La conversión de mayúsculas debe detectar los límites antes de normalizar, porque la transformación destruye la evidencia necesaria para analizar.