02822-hard-split

Back

type Split<S extends string, SEP extends string = never> = S extends `${infer R}${SEP}${infer F}` ? [R, ...Split<F, SEP>] : (S extends `${infer _}` ? (S extends SEP ? [] : [S]) : string[])

Solution by ouzexi #34294

// some helpers
type _split<S extends string, SEP extends string, ACC extends Array<any> = []>
  = S extends `${infer S1}${SEP}${infer Rest}`
    ? _split<Rest, SEP, [...ACC, S1]>
    : S extends `${SEP}` ? ACC : [...ACC, S]
  ;

type hasSeparator<Sep extends string | undefined> = Sep extends string
  ? Sep['length'] extends 0 ? false : true
  : false
;

type isLiteral<S extends string> = string extends S
  ? false
  : true
;

// main function
type Split<S extends string, SEP extends string = never> = hasSeparator<SEP> extends true
  ? isLiteral<S> extends true ? _split<S, SEP> : string[]
  : S
;

Solution by meta-panic #33550

// your answers
type __Split<S extends string, SEP extends string = ''> = Equal<S, string> extends true
  ? string[]
  : S extends ''
    ? []
    : S extends `${infer First}${SEP}${infer Rest}`
      ? [First, ...__Split<Rest, SEP>]
      : [S];

type Split<S extends string, SEP extends string = never> = [SEP] extends [never]
  ? [S]
  : S extends ''
    ? SEP extends ''
      ? []
      : ['']
    : __Split<S, SEP>;


Solution by kakasoo #32692

type Split<S extends string, SEP extends string = never> = [SEP] extends [never]
  ? [S]
  : S extends `${infer F}${SEP}${infer L}`
  ? [F, ...Split<L, SEP>]
  : string extends S
  ? string[]
  : SEP extends ""
  ? []
  : [S];

Solution by vangie #32246

   type SplitOptimal<S extends string, SEP extends string = 'default'> = string extends S
  ? string[]
  : S extends `${infer A}${SEP}${infer B}`
    ? [A, ...(B extends '' ? [] : SplitOptimal<B, SEP>)]
    : SEP extends ''
      ? []
      : [S]

Solution by chliguiy #31128

// your answers
type Split<T extends string, SEP extends string = never> = T extends `${infer P}${SEP}${infer L}`
 ? [P , ...Split<L, SEP>]
 : T extends `${infer _}`
   ? T extends SEP ? [] : [T]
   : string []

Solution by milletlovemouse #30920

type Split<S extends string, SEP extends string = `${S}1`> = S extends `${infer L}${SEP}${infer R}`
  ? [L, ...Split<R, SEP>]
  : string extends S
  ? string[]
  : SEP extends ''
  ? []
  : [S]

Solution by ln0y #30753

// your answers

type Split<S extends string, SEP extends string > = 
S extends ""
  ? SEP extends ""
    ? []
    : [S] : 
     S extends `${infer First}${SEP}${infer Rest}`
  ? [First, ...Split<Rest, SEP>]
  : string extends S
  ? string[]
  : [S] 

Solution by kerolossamir165 #30217

// your answers

type Split<S extends string, SEP extends string> = string extends S ? string[] : S extends `${infer First}${SEP}${infer Rest}` ? [First, ...Split<Rest, SEP>] : S extends SEP ? [] : [S]

Solution by 437204933 #29703

type Split<S, SEP extends string> = S extends `${infer F extends
  | string
  | SEP}${SEP}${infer R}`
  ? [F, ...Split<R, SEP>]
  : S extends `${infer R}` ? [R] : [];

  type result = Split<'Hi! How are you?', ' '> // -> ["Hi!", "How", "are", "you?"]

Solution by nuelsoft #29318

// your answers
type Split<S extends string, SEP extends string> = string extends S ? string[] : S extends '' ? SEP extends '' ? [] : [''] : S extends `${infer F}${SEP}${infer REST}` ? [F, ...Split<REST, SEP>] : [S];

Solution by yolilufei #29256

// If just the `string` type is provided, return string[]
type Split<S extends string, SEP extends string> = string extends S
  ? string[]
  // If string and seperator are the same, return empty array
  : Equal<S, SEP> extends true
    ? []
    // Else recursively split the string out
    : S extends `${infer First}${SEP}${infer Rest}`
      ? [First, ...Split<Rest, SEP>]
      : [S]

Solution by HubooDeclan #27032

type Split<
  S extends string,
  SEP extends string,
  Results extends string[] = []
> = string extends S
  ? string[]
  : S extends SEP
  ? Results
  : S extends `${infer Prefix}${SEP}${infer Suffix}`
  ? Split<Suffix, SEP, [...Results, Prefix]>
  : [...Results, S];

Solution by seeyoujeong #26696

type Split<S extends string, SEP extends string> = string extends S
  ? string[]
  : S extends `${infer L}${SEP}${infer R}`
  ? [L, ...Split<R, SEP>]
  : SEP extends ''
  ? []
  : [S];

Solution by JohnLi1999 #25819

type Split<S extends string, SEP extends string> = 
S extends `${infer First}${SEP}${infer Rest}` 
  ? [`${First}`, ...Split<Rest, SEP>]
  : string extends S ?  string[] : SEP extends '' ? [] : [`${S}`] 

Solution by JhonLandy #25794

type Split<S extends string, SEP extends string> =
  string extends S ? string[] :
  S extends `${infer P}${SEP}${infer R}` ? [P, ...Split<R, SEP>] :
  SEP extends `` ? [] : [S];

// old way
// type Split<S extends string, SEP extends string> = S extends `` ?
//   (SEP extends `` ? [] : [``]) :                //[``] or []
//   (S extends `${any}` ?                         //`xxxxx` (is templete)
//     (S extends `${infer F}${SEP}${infer R}` ?   //`aa_bb`
//       [F, ...Split<R, SEP>] :                   //[aa, ...[bb]]
//       [S]) :                                    //[bb]
//     string[]);                                  //string ==> string[] (unknown templete)

Solution by E-uler #24970

type Split<S extends string, SEP extends string> = Equal<string, S> extends true 
? string[] 
: S extends `${infer First}${SEP}${infer Rest}`
  ? [First, ...Split<Rest, SEP>]
  : S extends ''
    ? SEP extends ''
      ? []
      : ['']
    : [S]

Solution by NeylonR #24527

// your answers
type Split<S extends string, SEP extends string, Acc extends string[] = []> = string extends S ? S[] :
S extends `${infer F}${SEP}${infer R}` ?
Split<R, SEP, [...Acc, F]> : S extends '' ? SEP extends '' ? Acc : [''] : [...Acc, S]

Solution by snakeUni #23918

// your answers
// A internal helper to make the type tail recursive
type _Split<
  Str extends string, 
  Separator extends string | undefined = undefined, 
  Accumulator extends string[] = []
> =
  Separator extends undefined
    ? [...Accumulator, Str]
    : Str extends ""
      ? Separator extends ""
        // "".split("") -> []
        ? Accumulator
        // "".split(x) -> [""]
        : [...Accumulator, ""]
      : Str extends `${infer Line}${Separator}${infer Rest}`
        ? _Split<Rest, Separator, [...Accumulator, Line]>
        : [...Accumulator, Str]
        
/**
 * A type that converts a string type to a tuple by splitting it at the indicies
 * that match Separator.
 * @template Str - The string to split.
 * @template Separator - The string at which to split the given string.
 */
type Split<Str extends string, Separator extends string | undefined = undefined> =
  _Split<Str, Separator>;

Solution by jakub791 #23293

type Split<S extends string, SEP extends string, R extends string[] = []> =
  string extends S
    ? string[]
    : S extends `${infer A}${SEP}${infer Rest}`
      ? Split<Rest, SEP, [...R, A]>
      : S extends ''
        ? SEP extends ''
          ? R
          : ['']
        : [...R, S]

Solution by drylint #22335

type Split<S extends string, SEP extends string> = string extends S ?
string[] : S extends `${infer F}${SEP}${infer Rest}` ?
[F, ...Split<Rest, SEP>] : S extends '' ? SEP extends '' ? [] : [''] : [S];

Solution by Karamuto #22042

type Split<S extends string, SEP extends string> = 
  string extends S 
  ? string[] 
  : S extends ''
    ? SEP extends ''
      ? []
      : ['']
    : S extends `${infer A}${SEP}${infer B}`
      ? [A, ...Split<B, SEP>]
      : [S]

playground

Solution by zhaoyao91 #21558

// your answers
type Split<S extends string, SEP extends string,Arr extends any[] = []> =  string extends S ? 
string[] :
S extends `${infer F}${SEP}${infer L}` ? L extends '' ?
[...Arr,S] : 
Split<L,SEP,Arr extends [...infer Rest] ? [...Rest,F] : Arr> : 
Arr extends [] ?
SEP extends '' ? [] : [...Arr,S] : [...Arr,S]

Solution by YqxLzx #21418

type Split_<
  T extends string,
  SymbolDot extends string = "",
  Result extends Array<string> = []
> = string extends T
  ? string[]
  : [T, SymbolDot, Result] extends ["", infer R, []]
     ? [T]
  : T extends `${infer A}${SymbolDot}${infer B}`
    ? Split_<B, SymbolDot, [...Result, A]>
  : T extends ""
  ? Result
  : [...Result, T];

type Split<
  T extends string,
  SymbolDot extends string = "",
> = [T ,SymbolDot] extends ["",""]?[]: Split_<T,SymbolDot>;

Solution by so11y #21249

type Split<S extends string, SEP extends string> = string extends S
  ? string[]
  : S extends `${infer S}${SEP}${infer O}`
    ? [S, ...Split<O, SEP>]
    : [SEP] extends [''] ? [] : [S]

Solution by pengzhanbo #20472

// your answers
type Split<S extends string, D extends string> = S extends `${infer A}${D}${infer B}`? [A, ...Split<B, D>]: [S]

Solution by fengjinlong #20295

type Split<S extends string, SEP extends string> = Equal<S, string> extends true
  ? S[]
  : S extends `${infer F}${SEP}${infer R}`
  ? [F, ...Split<R, SEP>]
  : S extends ''
  ? SEP extends ''
    ? []
    : [S]
  : [S];

Solution by CaoXueLiang #19470

type Split<T extends string, TSep extends string> = 
    T extends `${infer TLeft}${TSep}${infer TRight}` ? [TLeft, ...Split<TRight, TSep>] : [T]

Solution by knazeri #19120

type SplitChar<
  S extends string,
  result extends string[] = []
> = S extends `${infer r}${infer rest}`
  ? SplitChar<rest, [...result, r]>
  : result;
type Split<
  S extends string,
  SEP extends string,
  resultArray extends string[] = [],
  result extends string = ""
> = string extends S
  ? string[]
  : SEP extends ""
  ? SplitChar<S>
  : S extends `${infer r}${infer rest}`
  ? r extends SEP
    ? Split<rest, SEP, [...resultArray, result], "">
    : Split<rest, SEP, resultArray, `${result}${r}`>
  : [...resultArray, result];

Solution by cc-hearts #18725

type Split<T extends string,S extends string> = T extends `${infer A}${S}${infer B}` ? [A, ...Split<B, S>] : [T]

Solution by ReiiYuki #17986