SnakeCase

Challenge

Create a SnakeCase<T> generic that turns a string formatted in camelCase into a string formatted in snake_case.

A few examples:

type res1 = SnakeCase<"hello">; // => "hello"
type res2 = SnakeCase<"userName">; // => "user_name"
type res3 = SnakeCase<"getElementById">; // => "get_element_by_id"

Solution

Die Idee zur Loesung dieses Problems ist es, mittels infer und Rekursion ueber die Zeichenkette zu laufen. Dabei pruefen wir fuer jedes Zeichen, ob dieses grosgeschrieben ist (Uppercase). Falls ja, fuegen wir es dem finalen String hinzu, und setzen wie es bei snake_case ueberlich ist, ein Unterstich vor das Zeichen. Ist das Zeichen bereits kleingeschrieben, so nehmen wir es einfach in die finale Zeichenkette / den Akkumulator auf.

type SnakeCase<
  T extends string,
  U extends string = ""
> = T extends `${infer H}${infer T}`
  ? H extends Uppercase<H>
    ? `${U}_${Lowercase<H>}${SnakeCase<T>}`
    : SnakeCase<T, `${U}${H}`>
  : U;

References

Infer types template string