ReplaceAll
Challenge
Implement ReplaceAll<S, From, To>
which replace the all the substring From
with To
in the given string S
.
For example:
type replaced = ReplaceAll<"t y p e s", " ", "">; // expected to be 'types'
Solution
We will base this solution on solution for Replace
type.
The input string S
must be split into three parts. The leftmost part before
From
, the From
itself, the rightmost part after the From
. We can do that
with conditional types and inferring.
Once the string is inferred and we know the parts, we can return a new template
literal type which is constructed from those parts and our required To
part:
type ReplaceAll<
S extends string,
From extends string,
To extends string,
> = From extends ""
? S
: S extends `${infer L}${From}${infer R}`
? `${L}${To}${R}`
: S;
This solution will replace a single match, but we need to replace all the matches. It is easily achievable by providing our new string as a type parameter to the type itself (recursively):
type ReplaceAll<
S extends string,
From extends string,
To extends string,
> = From extends ""
? S
: S extends `${infer L}${From}${infer R}`
? ReplaceAll<`${L}${To}${R}`, From, To>
: S;
However, on the next recursive call, characters can be replaced in not expected
way. For instance, calling ReplaceAll<"fooo", "fo", "f">
will lead to
foo -> fo -> f
. So that, we need to keep track of the string before:
type ReplaceAll<
S extends string,
From extends string,
To extends string,
Before extends string = "",
> = From extends ""
? S
: S extends `${Before}${infer L}${From}${infer R}`
? ReplaceAll<`${Before}${L}${To}${R}`, From, To, `${Before}${L}${To}`>
: S;
Comments