08767-medium-combination

Back

type Combination<T extends string[]> = T extends [infer F extends string, ...infer R extends string[]] ?
    R extends [] ? F : F | Combination<R>|`${F} ${Combination<R>}`|`${Combination<R>} ${F}`:
    '';

思路:通过extends + infer拆除第一项和剩余项,再用递归的思路,考虑如何拼接

Solution by ndfhsledk #34456

type Combination<T extends string[], A = T[number], I = A> = I extends string ?   I | `${I} ${Combination<[], Exclude<A, I>>}` : never

Solution by ouzexi #34103

type Combination<T extends string[], U = T[number], P = U> = P extends string
  ? P | `${P} ${Combination<T, Exclude<U, P>>}`
  : never;

Solution by DoubleWoodLin #28833

type CombinationHelper<
  U extends string,
  Acc extends string = never,
  UCopy extends string = U
> = [U] extends [never]
  ? Acc
  : U extends U
  ? CombinationHelper<
      Exclude<UCopy, U>,
      [Acc] extends [never] ? U : Acc | `${Acc} ${U}`
    >
  : never;

type Combination<T extends string[]> = CombinationHelper<T[number]>;

UCopy serves as the whole non-distributed union; U is our distributed type (through the U extends U)

Solution by alythobani #27614

type Combination<T extends string[], A = T[number], U = A> = 
  U extends string
    ? U | `${U} ${Combination<[], Exclude<A, U>>}`
    :never

Solution by smileboyi #27156

// your answers
type Combination<T extends string[], U = T[number], K = U> = K extends string
    ? K | `${K} ${Combination<[], Exclude<U, K>>}`
    : ''

Solution by studymachiney #24430

type Without<T extends any[], U> = T extends [infer F, ...infer R] ? U extends F ? Without<R, U> : [F, ...Without<R, U>] : []/*pop*/;
type Combination<T extends string[], U = T[number]> = U extends T[number] ? U | `${U} ${Combination<Without<T, U>>}` : never;

// old way
// type ToUnion<T extends string[]> = T extends [infer F extends string, ...infer R extends string[]] ? F | ToUnion<R> : never;
// type UnionComb<T extends string, U = T> = U extends T ? U | `${U} ${UnionComb<Exclude<T, U>>}` : ``;

// type Combination<T extends string[]> = UnionComb<ToUnion<T>>;

Solution by E-uler #24004

type NumberRange<L, H, Acc extends (number|never)[] = []> =
  Acc['length'] extends H ? [...Acc, H][number] :
  Acc['length'] extends L ? NumberRange<[...Acc, Acc['length']]['length'], H, [...Acc, Acc['length']]> :
  NumberRange<L, H, [...Acc, never]>

Solution by flavianh #23400

// your answers
type Combination<T extends string[], U = T[number], U1 = U> =
  U extends string
    ? U | `${U} ${Combination<[], Exclude<U1, U>>}`
    : never

Solution by snakeUni #23240

type Combination<T extends string[], U = T[number], K = U> = K extends string ? K | `${K} ${Combination<[], Exclude<U, K>>}` : ''

Solution by asurewall #23119

// your answers
type Combination<T extends string[], U = T[number], U1 = U> =
  U extends string
    ? U | `${U} ${Combination<[], Exclude<U1, U>>}`
    : never

Solution by jxhhdx #22752

type Combination<T extends string[], U = T[number], U1 = U> =
  U extends string
    ? U | `${U} ${Combination<[], Exclude<U1, U>>}`
    : never

Solution by drylint #22105

// your answers

type Combination<T extends string[], U = T[number], K = U> = K extends string ? K | `${K} ${Combination<[], Exclude<U, K>>}` : '';

Solution by Quanzhitong #20792

type Combination<T extends Array<string>,P  = T[number],S = P> =
S extends `${infer A extends string}` ? 
S | `${A} ${Combination<[],Exclude<P,A>>}` : ""
;

Solution by so11y #20705

// your answers
type Combination<T extends string[], U = T[number], K = U> = K extends string ? K | `${K} ${Combination<[], Exclude<U, K>>}` : '';

Solution by YqxLzx #20242

// your answers
type CombinationForUnion<
  U extends string,
  T extends string = U
> = T extends unknown
  ? T | `${T} ${CombinationForUnion<Exclude<U, T>>}`
  : never;
type arr = ["1", "2", "3"];
type arrr = CombinationForUnion<arr[number]>;
// expected to be `"foo" | "bar" | "baz" | "foo bar" | "foo bar baz" | "foo baz" | "foo baz bar" | "bar foo" | "bar foo baz" | "bar baz" | "bar baz foo" | "baz foo" | "baz foo bar" | "baz bar" | "baz bar foo"`
type Keys = Combination<["foo", "bar", "baz"]>;
type Combination<Arr> = CombinationForUnion<Arr[number]>;

Solution by fengjinlong #20102

type CombinationForUnion<U extends string, S extends string = U> = 
  S extends unknown
    ? S | `${S} ${CombinationForUnion<Exclude<U, S>>}`
    : never

type Combination<T extends string[]> = CombinationForUnion<T[number]>

Solution by zhaoyao91 #19861

// your answers
type Combination<T extends string[], U = T[number], I = U> = I extends infer R extends string
    ? R | `${R} ${Combination<T, Exclude<U, I>>}`
    : never;

Solution by bucketCocoa #19619

type Combination<T extends string[], U = T[number], K = U> = K extends string ? K | `${K} ${Combination<[], Exclude<U, K>>}` : '';

Solution by CaoXueLiang #18700

type Combination<T extends string[], U = T[number], I = U> = I extends U
  ? I extends string
    ? I | `${I} ${Combination<T, Exclude<U, I>>}`
    : never
  : never
type Combination<T extends string[], U = T[number], I = U> =
  I extends infer S extends string
    ? S | `${S} ${Combination<T, Exclude<U, I>>}`
    : never

Solution by milletlovemouse #18005

type Combination<T extends string[], U = T[number], K = U> =
  K extends string
    ? K | `${ K } ${ Combination<[], Exclude<U, K>> }`
    : ''

Solution by lvjiaxuan #17982

type Combination<T extends string[], U = T[number], K = U> = K extends U
  ? K extends string
    ? K | `${K} ${Combination<[], Exclude<U, K>>}`
    : ""
  : "";

Solution by cc-hearts #17966

type ToUnion<T extends unknown[]> = T[number]
type ExcludeItem<T extends unknown[], S, Res extends unknown[] = []> =
  T extends [infer F, ...infer R]
    ? S extends F
      ? ExcludeItem<R, S, Res>
      : ExcludeItem<R, S, [...Res, F]>
    : Res

type Combination<T extends string[], U extends string = ToUnion<T>> =
  [U] extends [never]
    ? never
    : U extends U
      ? Combination<ExcludeItem<T, U>> extends never
        ? `${U}`
        : `${U} ${Combination<ExcludeItem<T, U>>}` | Combination<ExcludeItem<T, U>>
      : never

Solution by YOUNGmaxer #17892

type Constraint = string | number | bigint | boolean | null | undefined;
type Join<
  T extends unknown[],
  U extends Constraint,
  Result extends string = ''
> = T extends [infer F extends Constraint, ...infer R] ?
  Join<R, U, F extends '' ? Result : `${Result}${Result extends '' ? '' : U}${F}`> :
  Result;
type GetCombination<
  T extends Constraint[],
  U = T[number] | '',
  K = U
> = T extends [infer _, ...infer R extends Constraint[]] ?
  K extends K ?
    Join<[K, GetCombination<R, K extends '' ? U : Exclude<U, K>>], ' '> :
    ''
  : '';
type Combination<T extends Constraint[]> = Exclude<GetCombination<T>, ''>;

Solution by CallMeSaltyF1sh #17203

Question & Answer

type Combination<T extends string[]> =
  Exclude<Join<UnionToCombinationList<T[number]>, ' '>, ''>

type UnionToCombinationList<U extends string, Item extends string = U> = [U] extends [never]
  ? []
  : Item extends Item
  ? [...([Item] | []), ...UnionToCombinationList<Exclude<U, Item>>]
  : []
type Join<T extends unknown[], U extends string | number> =
  T extends [infer Head, ...infer Tail]
    ? Head extends string | number
      ? Tail extends []
        ? Head
        : `${Head}${U}${Join<Tail, U>}`
      : ''
    : never

Solution by doobee98 #16788

// your answers
type Combination<_T extends string[], All extends string = _T[number], Current = All> = Current extends string 
                                                                                    ? Current | `${Current} ${Combination<[], Exclude<All, Current>>}`
                                                                                    : never;

Solution by jiaaoMario #16695

// your answers

type Combination<T extends string[], U = T[number], D = U> = D extends string
  ? `${D}` | `${D} ${Combination<[], Exclude<U, D>>}`
  : never

Solution by humandetail #16300

type Combination<T extends string[], All = T[number], One = All> =  One extends string
  ? One | `${One} ${Combination<[], Exclude<All, One>>}`
  : never
;

Solution by alexfung888 #15684

// your answers
type CombinationFromUnion<
U extends string,
AllofU extends string=U> = 
U extends U|infer V
? [V] extends [never]
? U
: U|`${U} ${CombinationFromUnion<Exclude<AllofU,U>>}`
:never

type Combination<
    T extends readonly string[]>=
    CombinationFromUnion<T[number]> ;

Solution by justBadProgrammer #15528

// your answers
type Combination<T extends string[], U = T[number], A = U> = U extends infer U extends string
  ? `${U} ${Combination<T, Exclude<A, U>>}` | U
  : never;


Solution by SeptEarlyMorning #12024