type DropString<S, R> = S extends `${infer First}${infer Rest}`
? R extends `${string}${First}${string}`
? DropString<Rest, R>
: `${First}${DropString<Rest, R>}`
: S
Solution by 2083335157 #35062
type Drop<T extends string, P extends string> = T extends `${infer R}${P}${infer F}` ? Drop<`${R}${F}`, P> : T
type DropString<S extends string, R extends string> = R extends `${infer V}${infer rest}` ? DropString<Drop<S, V>, rest> : S
Solution by ouzexi #34277
type DropString<
S extends string,
R extends string
> = S extends `${infer Ch}${infer Rest}`
? R extends `${string}${Ch}${string}`
? DropString<Rest, R>
: `${Ch}${DropString<Rest, R>}`
: "";
Solution by Vampirelee #32635
type DropOne<S extends string, C extends string> =
S extends `${infer Head}${C}${infer Tail}`
? DropString<`${Head}${Tail}`, C>
: S
type DropString<S extends string, R extends string> =
R extends `${infer F}${infer Rest}`
? DropString<DropOne<S, F>, Rest>
: S
Solution by action-hong #32424
type FirstChar<T extends string> = T extends `${infer C}${string}` ? C : never;
type Shift<T extends string> = T extends `${string}${infer R}` ? R : never;
type Trim<T extends string> = T extends `${infer F} ${infer R}`
? `${F}${Trim<R>}`
: T;
type DropString<S extends string, R extends string> = R extends " "
? Trim<S>
: R extends ""
? S
: S extends `${infer First}${FirstChar<R>}${infer Rest}`
? DropString<`${First}${Rest}`, R>
: DropString<S, Shift<R>>;
Solution by idebbarh #30842
type Str2Arr<T> = T extends `${infer A}${infer B}` ? [A, ...Str2Arr<B>] : []
type DropString<S, R> = S extends `${infer A}${infer B}` ? A extends Str2Arr<R>[number] ? DropString<B, R> : `${A}${DropString<B, R>}` : S
Solution by dreamluo-plus #30775
type Includes<S, R extends string> = S extends '' ? false : S extends `${infer A}${R}${infer B}` ? true : false
type DropString<S, R extends string, U extends string = ''> = S extends`${infer A}${infer B}` ? Includes<R, A> extends true ? DropString<B, R, U> : DropString<B, R, `${U}${A}`> : U
Solution by dreamluo-plus #30573
type Includes<S extends string, R> = R extends `${string}${S}${string}` ? true : false
type DropString<S, R> = S extends `${infer A}${infer B}` ? Includes<A, R> extends true ? DropString<B, R> : `${A}${DropString<B, R>}` : ''
Solution by dreamluo-plus #30351
// your answers
type GetStringAry<T> = T extends `${infer First}${infer Rest}` ? [First, ...GetStringAry<Rest>] : []
type First<S> = S extends `${infer First}${infer Rest}` ? First : ''
type Tail<S> = S extends `${infer First}${infer Rest}` ? Rest : ''
type GetRes<S, U> = S extends ''? '' : First<S> extends U ? `${GetRes<Tail<S>, U>}`: `${First<S>}${GetRes<Tail<S>, U>}`
type DropString<S, R> = GetRes<S, GetStringAry<R>[number]>
Solution by 437204933 #29702
type DropString<S, R, T extends string = ''> =
S extends `${infer First}${infer Rest}`
? DropString<Rest, R, `${T}${R extends `${string}${First}${string}` ? '' : First}`>
: T
Solution by smileboyi #28134
type StringToUnion<S> = S extends `${infer F}${infer R}`
? F | StringToUnion<R>
: never;
type DropString<
S,
R,
U = StringToUnion<R>
> = S extends `${infer F}${infer REST}`
? `${F extends U ? '' : F}${DropString<REST, R, U>}`
: '';
Solution by JohnLi1999 #25812
We've already done a similar challenge, DropChar which will drop a specific sequence of characters. This one is a bit more complex because it will drop any individual character in the provided pattern. Loops within loops. Turtles all the way down.
// ============= Test Cases =============
import type { Equal, Expect } from './test-utils'
type A1 = DropString<'butter fly!', ''>;
type B1 = 'butter fly!';
type C1 = Expect<Equal<A1, B1>>;
type A2 = DropString<'butter fly!', ' '>;
type B2 = 'butterfly!';
type C2 = Expect<Equal<A2, B2>>;
type A3 = DropString<'butter fly!', 'but'>;
type B3 = 'er fly!';
type C3 = Expect<Equal<A3, B3>>;
type A4 = DropString<' b u t t e r f l y ! ', 'but'>;
type B4 = ' e r f l y ! ';
type C4 = Expect<Equal<A4, B4>>;
type A5 = DropString<' butter fly! ', ' '>;
type B5 = 'butterfly!';
type C5 = Expect<Equal<A5, B5>>;
type A6 = DropString<' b u t t e r f l y ! ', ' '>;
type B6 = 'butterfly!';
type C6 = Expect<Equal<A6, B6>>;
type A7 = DropString<' b u t t e r f l y ! ', 'but'>;
type B7 = ' e r f l y ! ';
type C7 = Expect<Equal<A7, B7>>;
type A8 = DropString<' b u t t e r f l y ! ', 'tub'>;
type B8 = ' e r f l y ! ';
type C8 = Expect<Equal<A8, B8>>;
type A9 = DropString<' b u t t e r f l y ! ', 'b'>;
type B9 = ' u t t e r f l y ! ';
type C9 = Expect<Equal<A9, B9>>;
type A10 = DropString<' b u t t e r f l y ! ', 't'>;
type B10 = ' b u e r f l y ! ';
type C10 = Expect<Equal<A10, B10>>;
// ============= Your Code Here =============
type DropString<T, U> =
T extends `${infer Head}${infer Tail}`
? U extends `${string}${Head}${string}`
? DropString<Tail, U>
: `${Head}${DropString<Tail, U>}`
: '';
// ============== Alternatives ==============
type DropChar<T, U extends string> =
T extends `${infer Left}${U}${infer Right}`
? DropChar<`${Left}${Right}`, U>
: T;
type DropString<T, U> =
U extends `${infer Head}${infer Tail}`
? DropString<DropChar<T, Head>, Tail>
: T;
For more video solutions to other challenges: see the umbrella list! https://github.com/type-challenges/type-challenges/issues/21338
Solution by dimitropoulos #25352
type ToUnion<T extends string> = T extends `${infer F}${infer R}` ? F | ToUnion<R> : never;
type DropString<S extends string, R extends string> = S extends `${infer F}${infer Rest}` ? `${F extends ToUnion<R> ? `` : F}${DropString<Rest, R>}` : ``;
Solution by E-uler #24968
type StringToUnion<T extends string> = T extends `${infer First}${infer Rest}`
? Rest extends ''
? First
: First | StringToUnion<Rest>
: never
type DropString<S extends string, R extends string> = S extends `${infer First}${infer Rest}`
? First extends StringToUnion<R>
? DropString<Rest,R>
: `${First}${DropString<Rest, R>}`
: ''
Solution by NeylonR #24526
// your answers
type Includes<S, R> = S extends `${infer F}${infer Rest}` ? R extends F ? true : Includes<Rest, R> : false
type DropString<S, R, Acc extends string = ''> = S extends `${infer F}${infer Rest}` ?
Includes<R, F> extends true ? DropString<Rest, R, Acc> : DropString<Rest, R, `${Acc}${F}`> : Acc
Solution by snakeUni #23916
type String2Char<R extends string> = R extends `${infer F}${infer L}` ? F | String2Char<L> : '';
type DropString<S extends string, R extends string, RChar = String2Char<R>> =
S extends `${infer CheckChar}${infer LastChar}`
? `${(CheckChar extends RChar ? '' : CheckChar)}${DropString<LastChar, R>}`
: ''
Solution by litangmm #23607
// your answers
type StringToUnion<S extends string> = S extends `${infer F}${infer R}` ? F | StringToUnion<R> : never;
type DropString<
S extends string,
R extends string
> = S extends `${infer F}${infer L}`
? F extends StringToUnion<R>
? `${DropString<L, R>}`
: `${F}${DropString<L, R>}`
: S;
Solution by jxhhdx #23580
type DropString<T extends string, U extends string> = U extends `${infer F}${infer R}`
? `${DropString<T extends `${infer A}${infer B}`? `${A extends F ? '': A}${DropString<B, F>}`: '',R>}`
: T
Solution by TKBnice #23323
type DropString<S extends string, U extends string> =
S extends `${infer A}${infer Rest}`
? `${U extends `${infer _}${A}${infer _}` ? '' : A}${DropString<Rest, U>}`
: ''
Solution by drylint #22745
type StringToUnion<T extends string> = T extends `${infer F}${infer Rest}` ? F | StringToUnion<Rest> : undefined;
type DropString<S, R extends string> = S extends `${infer First}${infer Rest}` ?
`${First extends StringToUnion<R> ? '' : First}${DropString<Rest, R>}` : '';
Solution by Karamuto #22038
// type Drop<S extends string, C extends string>
// = S extends `${infer F}${C}${infer R}` ? Drop<`${F}${R}`, C> : S
// type DropString<S extends string, R extends string>
// = R extends `${infer F}${infer R}` ? DropString<Drop<S, F>, R> : S;
type DropString<S extends string, R extends string>
= S extends `${infer A}${infer B}`
? `${R extends `${any}${A}${any}` ? '' : A}${DropString<B, R>}`
: S
Solution by goddnsgit #21916
type DropString<S extends string, R extends string> =
R extends ''
? S
: S extends `${infer First}${infer Rest}`
? R extends `${any}${First}${any}` // key point, check if `R` includes `First`
? DropString<Rest, R>
: `${First}${DropString<Rest, R>}`
: S
Solution by zhaoyao91 #21506
// your answers
type SToUnition<S extends string,A extends any[] = []> = S extends `${infer F}${infer R}` ? SToUnition<R,A extends [...infer Rest] ? [...Rest,F] : [F]> : A[number]
type DropString<S, R extends string, T extends string = ''> = S extends `${infer F}${infer Rest}` ?
F extends SToUnition<R> ? DropString<Rest,R,T extends `${infer P}` ? P : F> : DropString<Rest,R,T extends `${infer P}` ? `${P}${F}` : F>
: T
Solution by YqxLzx #21335
type StringToUnion<T extends string> = T extends `${infer F}${infer O}`
? F | StringToUnion<O>
: never
type DropString<S extends string, R extends string> = S extends `${infer F}${infer O}`
? `${F extends StringToUnion<R> ? '' : F}${DropString<O, R>}`
: S
Solution by pengzhanbo #20511
// your answers
type Ste<str, s, r extends string = ""> = str extends `${infer a}${infer b}`
? a extends s
? Ste<b, s, r>
: Ste<b, s, `${r}${a}`>
: r;
type DropString<str, s> = s extends `${infer a}${infer b}`
? DropString<Ste<str, a>, b>
: Ste<str, s>;
Solution by fengjinlong #20293
type StringToUnion<S, Total extends unknown[] = []> = S extends `${infer F}${infer R}` ? StringToUnion<R, [...Total, F]> : Total[number];
type DropString<S extends string, D extends string, Result extends string = ''> = S extends `${infer F}${infer R}`
? F extends StringToUnion<D>
? DropString<R, D, Result>
: DropString<R, D, `${Result}${F}`>
: Result;
Solution by CaoXueLiang #19262
type DropChar<S, R extends string> = S extends `${infer F}${R}${infer E}` ? `${F}${DropChar<E, R>}` : S;
type DropString<S, R extends string> = R extends `${infer F}${infer E}` ? DropString<DropChar<S, F>, E> : S;
Solution by BulatDashiev #16943
type StringToUnion${infer R}${infer S}
? R | StringToUnion : never;
type DropString<T extends string, R extends string, Q = StringToUnion${infer F}${infer Rest}
? F extends Q ?
DropString<Rest, R, Q, S> : DropString<Rest, R, Q, ${S}${F}
> : S;
Solution by my5201314zwl #16691
type StringToUnion${infer R}${infer S}
? R | StringToUnion : never;
type DropString<T extends string, R extends string, Q = StringToUnion${infer F}${infer Rest}
? F extends Q ?
DropString<Rest, R, Q, S> : DropString<Rest, R, Q, ${S}${F}
> : S;
Solution by my5201314zwl #16690
// your answers
type DropString<S, R extends string, U = StringToUnion<R>> = S extends `${infer F}${infer Rest}`
? F extends U
? DropString<Rest, R, U>
: `${F}${DropString<Rest, R, U>}`
: S
Solution by humandetail #16483