KebabCase

Challenge

Replace the camelCase or PascalCase string with kebab-case.

FooBarBaz -> foo-bar-baz

For example

type FooBarBaz = KebabCase<"FooBarBaz">;
const foobarbaz: FooBarBaz = "foo-bar-baz";

type DoNothing = KebabCase<"do-nothing">;
const doNothing: DoNothing = "do-nothing";

Solution

Zur Lösung des Problems laufen wir mittels template Literal Types über die Zeichenkette und prüfen jeweils, ob der restliche Teil der infereten Typ-Variablen mit einem Großbuchstaben beginnt, und falls ja, fügen wir ein Bindestrich ein, und rufen den Typen rekursiv für den Rest der Zeichenkette auf:

type KebabCase<S extends string> = S extends `${infer Head}${infer Tail}`
  ? // Bsp. Tail = "Foo" => Tail extends Uncap... ergibt false, daher wird der False-Branch ausgefuerht und ein Bindestrick ergaenzt.
    Tail extends Uncapitalize<Tail>
    ? `${Uncapitalize<Head>}${KebabCase<Tail>}`
    : `${Uncapitalize<Head>}-${KebabCase<Tail>}`
  : S;

References