Проблема

Удалите указанный символ со строки. Например:

type Butterfly = DropChar<" b u t t e r f l y ! ", " ">; // 'butterfly!'

Решение

Чтобы решить эту проблему, нужно знать, что такое шаблонные тип литералы в TypeScript. Вы можете более подробно о них почитать на их сайте.

Когда мы используем шаблонные тип литералы, мы можем выводить части строк этого литерала. Воспользуемся этим, чтобы вывести левую и правую части литерала. А разделителем будет сам символ, который нам нужно удалить.

type DropChar<S, C> = S extends `${infer L}${C}${infer R}` ? never : never;

С такой записью, мы получим ошибку компиляции Type ‘C’ is not assignable to type ‘string | number | bigint | boolean | null | undefined’.. Добавим ограничение на дженериках, чтобы этого избежать.

type DropChar<S, C extends string> = S extends `${infer L}${C}${infer R}`
  ? never
  : never;

Теперь, мы видим что у нас есть две части литерала и отдельно разделитель. Так как нам нужно разделитель удалить, то мы возвращаем только левую и правую части.

type DropChar<S, C extends string> = S extends `${infer L}${C}${infer R}`
  ? `${L}${R}`
  : never;

Таким образом, мы удалили один символ со строки. Чтобы продолжить удалять остальные, вызовем наш тип рекурсивно.

type DropChar<S, C extends string> = S extends `${infer L}${C}${infer R}`
  ? DropChar<`${L}${R}`, C>
  : never;

Мы покрыли все случаи, кроме случая, когда совпадений по шаблону нет. Если такая ситуация приключилась, вернём входную строку без изменений.

type DropChar<S, C extends string> = S extends `${infer L}${C}${infer R}`
  ? DropChar<`${L}${R}`, C>
  : S;

Что почитать