CamelCase
Завдання
Перевести рядок до CamelCase. Наприклад:
type camelCased = CamelCase<"foo-bar-baz">; // expected "fooBarBaz"
Розв’язок
Спільною частиною, яку ми можемо використати для виведення рядка є дефіс. Давайте виведемо частини до та після дефісу.
type CamelCase<S> = S extends `${infer H}-${infer T}` ? never : never;
Якщо такого шаблону немає - повертаємо рядок без змін.
type CamelCase<S> = S extends `${infer H}-${infer T}` ? never : S;
Але коли такий шаблон знайдений нам потрібно видалити дефіс та зробити першу букву великою. Крім цього не забуваємо, що можуть бути інші під-рядки, які також потрібно обробити. Зробимо це рекурсивно.
type CamelCase<S> = S extends `${infer H}-${infer T}`
? `${H}${CamelCase<Capitalize<T>>}`
: S;
Тепер проблема в тому, що ми не враховуємо випадок, коли друга частина рядка уже починається з великої літери. Виправимо це перевіркою чи можемо ми присвоїти цю частину до неї ж, але капіталізованої.
type CamelCase<S> = S extends `${infer H}-${infer T}`
? T extends Capitalize<T>
? never
: `${H}${CamelCase<Capitalize<T>>}`
: S;
Що робити, якщо друга частина рядка уже починається з великої літери? Збережемо дефіс та пропустимо цю частину. Звісно, також рекурсивно.
type CamelCase<S> = S extends `${infer H}-${infer T}`
? T extends Capitalize<T>
? `${H}-${CamelCase<T>}`
: `${H}${CamelCase<Capitalize<T>>}`
: S;
Чудово, ми отримали тип, що приводить шаблонні літерали до “camelCase”!
Коментарі