Camelize

Challenge

Implement Camelize which converts object from snake_case to to camelCase

Camelize<{
  some_prop: string;
  prop: { another_prop: string };
  array: [{ snake_case: string }];
}>;

// expected to be
// {
//   someProp: string,
//   prop: { anotherProp: string },
//   array: [{ snakeCase: string }]
// }

Solution

Zur Lösung dieses Problems definieren wir wieder einen Hilfstypen, der einen Schlüssel / Eigenschaft von Snake- zu Camelcase umwandelt:

type SnakeToCamel<T> = T extends `${infer H}_${infer C}${infer R}`
  ? `${H}${Uppercase<C>}${SnakeToCamel<R>}`
  : T;

Anschließend können wir diesen Hilfstyp SnakeToCamel verwenden, um die Schlüssel des neuen mapped types umzuwandeln. Sollte der Wert zu einem Schlüssel ein Tupel sein, so rufen wir den Typ für alle Elemente der Tupel auf.

type Camelize<T> = T extends Record<string, unknown>
  ? { [key in keyof T as SnakeToCamel<key>]: Camelize<T[key]> }
  : T extends [infer F, ...infer Rest]
  ? [Camelize<F>, ...Camelize<Rest>]
  : T;

References