Проблема

Реализовать Replace<S, From, To> который заменяет искомую строку From в S на строку To. Например:

type replaced = Replace<"types are fun!", "fun", "awesome">; // expected to be 'types are awesome!'

Решение

Начнем с того, что разобъем строку на три части: подстрока до From, сама подстрока From и подстрока после From. Используя условные типы этого легко добиться:

type Replace<
  S,
  From extends string,
  To,
> = S extends `${infer L}${From}${infer R}` ? S : S;

Как только TypeScript вывел типы, это означает что From найден и окружающие его части попадают в тип параметры L и R. Вернём новый строчный тип литерал, который создаем из этих выведенных кусков и строки To.

type Replace<
  S,
  From extends string,
  To extends string,
> = S extends `${infer L}${From}${infer R}` ? `${L}${To}${R}` : S;

Решение работает без проблем, кроме случая, когда From это пустая строка. В таком случае, TypeScript не сможет вывести типы. Починим это, как отдельный случай для пустой строки:

type Replace<
  S extends string,
  From extends string,
  To extends string,
> = From extends ""
  ? S
  : S extends `${infer L}${From}${infer R}`
  ? `${L}${To}${R}`
  : S;

Что почитать