joobang/type-challenges

no - 8767 - Combination

Closed this issue · 1 comments

type Combination<T extends string[], All = T[number], Item = All>
  = Item extends string
    ? Item | `${Item} ${Combination<[], Exclude<All, Item>>}`
    : never
import type { Equal, Expect } from '@type-challenges/utils'

type test = Combination<['foo', 'bar', 'baz']>;

type cases = [
  Expect<Equal<Combination<['foo', 'bar', 'baz']>, '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'>>,
  Expect<Equal<Combination<['apple', 'banana', 'cherry']>, 'apple' | 'banana' | 'cherry' |
  'apple banana' | 'apple cherry' | 'banana apple' | 'banana cherry' | 'cherry apple' | 'cherry banana' |
  'apple banana cherry' | 'apple cherry banana' | 'banana apple cherry' | 'banana cherry apple' | 'cherry apple banana' | 'cherry banana apple'>>,
  Expect<Equal<Combination<['red', 'green', 'blue', 'yellow']>, 'red' | 'green' | 'blue' | 'yellow' |
  'red green' | 'red blue' | 'red yellow' | 'green red' | 'green blue' | 'green yellow' | 'blue red' | 'blue green' | 'blue yellow' | 'yellow red' | 'yellow green' | 'yellow blue' |
  'red green blue' | 'red green yellow' | 'red blue green' | 'red blue yellow' | 'red yellow green' | 'red yellow blue' |
  'green red blue' | 'green red yellow' | 'green blue red' | 'green blue yellow' | 'green yellow red' | 'green yellow blue' |
  'blue red green' | 'blue red yellow' | 'blue green red' | 'blue green yellow' | 'blue yellow red' | 'blue yellow green' |
  'yellow red green' | 'yellow red blue' | 'yellow green red' | 'yellow green blue' | 'yellow blue red' | 'yellow blue green' |
  'red green blue yellow' | 'red green yellow blue' | 'red blue green yellow' | 'red blue yellow green' | 'red yellow green blue' | 'red yellow blue green' |
  'green red blue yellow' | 'green red yellow blue' | 'green blue red yellow' | 'green blue yellow red' | 'green yellow red blue' | 'green yellow blue red' |
  'blue red green yellow' | 'blue red yellow green' | 'blue green red yellow' | 'blue green yellow red' | 'blue yellow red green' | 'blue yellow green red' |
  'yellow red green blue' | 'yellow red blue green' | 'yellow green red blue' | 'yellow green blue red' | 'yellow blue red green' | 'yellow blue green red'>>
  ,
  Expect<Equal<Combination<['one', 'two']>, 'one' | 'two' |
  'one two' | 'two one'>>,
]
  1. T extends string[]: T는 문자열 배열이어야 합니다.
  2. All = T[number]: All은 배열 T의 모든 요소들을 나타냅니다.
  3. Item = All: 기본적으로 Item은 All의 모든 요소 중 하나입니다.
  4. Item extends string: Item이 문자열인 경우 조건부 타입이 적용됩니다.
  5. ? Item | ${Item} ${Combination<[], Exclude<All, Item>>}: Item 자체 또는 Item과 나머지 All 요소들의 조합을 표현합니다. ${Item} ${Combination<[], Exclude<All, Item>>}는 Item을 제외한 나머지 요소들로 재귀적으로 호출하여 조합을 생성합니다.
  6. : never: Item이 문자열이 아닌 경우 결과는 never입니다.
  • ['a', 'b', 'c'] 배열이 주어지면, 결과 타입은 'a' | 'b' | 'c' | 'a b' | 'a c' | 'b a' | 'b c' | 'c a' | 'c b' | 'a b c' | 'a c b' | ... 등의 형태가 됩니다.