I am trying to implement a generic split type in TypeScript that is able to split a literal string using multiple delimiters.
type Spl<T extends string, D extends string> = T extends `${infer A}${D}${infer B}` ?
A extends '' ? [] :
[A, ...Spl<B, D>] : (T extends '' ? [] : [T]);
type SplMany<T extends string, D extends string[]> = D extends [infer H extends string, ...infer Tail extends string[]]
?
T extends '' ? [] : SplManyInputsManyDelimieter<[...Spl<T, H>], Tail>
: [T];
type SplManyInputs<T extends string[], D extends string> = T extends [infer H extends string, ...infer Tail extends string[]]
? [...Spl<H, D>, ...SplManyInputs<Tail, D>] : [];
type SplManyInputsManyDelimieter<T extends string[], D extends string[]> =
D extends [infer H extends string, ...infer Tail extends string[]] ?
SplManyInputsManyDelimieter<[...SplManyInputs<T, H>], Tail>
: T;
type t1 = Spl<'1 2 3 4 5 6 7 8 9 10 11 %test% 12 13 14 15 16 17 18 19 20 21 22 23 24 25 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 1 2 3 4 5 6 7 8 9 10 11 %test% 12 13 14 15 16 17 18 19 20 21 22 23 24 25 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 1 2 3 4 5 6 7 8 9 10 11 %test% 12 13 14 15 16 17 18 19 20 21 22 23 24 25 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 1 2 3 4 5 6 7 8 9 10 11 %test% 12 13 14 15 16 17 18 19 20 21 22 23 24 25 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 1 2 3 4 5 6 7 8 9 10 11 %test% 12 13 14 15 16 17 18 19 20 21 22 23 24 25 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4', ' '>;
type t1_ = Spl<'1 ', ' '>;
type t1__ = Spl<'1', ' '>;
type t1___ = Spl<'', ' '>;
type t3 = SplManyInputs<[' 1 2 3 ', ' 3 4 ', '5 6'], ' '>;
type t3_ = SplManyInputs<[], ' '>;
type t4 = SplManyInputsManyDelimieter<['1 2', '3 4', '5 6'], [' ']>;
type t4_ = SplManyInputsManyDelimieter<['1 2', '3 4', '5 6'], []>;
type t4__ = SplManyInputsManyDelimieter<[], [' ']>;
type test = SplMany<'0_1 0_2 0_3 0_4 0_5 0_6 0_7 0_8 0_9 1_0 1_1 1_2 1_3 1_4 1_5 1_6 1_7 1_8 1_9 2_0 2_1 2_2 2_3 2_4 2_5 2_6 2_7 2_8 2_9 3_0 3_1 3_2 3_3 3_4 3_5 3_6 3_7 3_8 3_9 4_0 4_1 4_2 4_3 4_4 4_5 4_6 4_7 4_8', [' ', '_']> // error!
// Type instantiation is excessively deep and possibly infinite.
See the TS playground link
The code works but when the input gets long enough, I get the error Type instantiation is excessively deep and possibly infinite. ts(2589)
. I guess splitting this way is not very efficient but I expected the recursion limit to be somewhat higher.
Are there any tricks I can do optimize the code to allow for longer inputs? I also tried to find the part of the TypeScript compiler responsible for the error message but could not find it. Does anyone know where the error is emitted?