FE/type-challenge
21106. Combs
최토피
2023. 10. 10. 12:00
728x90
문제
- Combine multiple modifier keys, but the same modifier key combination cannot appear.
- In the
ModifierKeys
provided, the priority of the previous value is higher than the latter value; that is,cmd ctrl
is OK, butctrl cmd
is not allowed.
cases
type ModifierKeys = ['cmd', 'ctrl', 'opt', 'fn']
type CaseTypeOne = 'cmd ctrl' | 'cmd opt' | 'cmd fn' | 'ctrl opt' | 'ctrl fn' | 'opt fn'
type cases = [
Expect<Equal<Combs<ModifierKeys>, CaseTypeOne>>,
]
정답
type Combs<T extends any[]> = T extends [infer T1 extends string, ...infer RestT extends string[]]
? RestT['length'] extends 0
? never
: `${T1} ${RestT[number]}` | Combs<RestT>
: never
풀이
조건
- 앞에서 순서대로 2개씩 조합을 한다.
- 아이템은 순서대로 우선순위가 있어, 결과물도 우선순위에 따라 배치가 되어야 한다.
해설
우선순위에 따라 결과물의 배치에는 순서가 있으므로, 앞에서 순차적으로 접근하여 조합하도록 한다.
따라서 다음과 같이 순서대로 조합을 얻어내고, 나머지 배열은 재귀적으로 접근하여 결과물을 얻을 수 있도록 한다.
type Combs<T extends any[]> = T extends [infer T1 extends string, ...infer RestT extends string[]]
? RestT['length'] extends 0
? never
: Modify<T1, RestT> | Combs<RestT>
: never
Modify
는 조합을 얻어내는 타입으로 다음과 같이 구현할 수 있다.
type Modify<T extends string, Candidates extends string[]>
= Candidates extends [infer C1 extends string, ...infer Rest extends string[]]
? `${T} ${C1}` | Modify<T, Rest>
: never
이 둘을 조합하면 다음과 같다.
type Combs<T extends any[]> = T extends [infer T1 extends string, ...infer RestT extends
? RestT['length'] extends 0
? never
: Modify<T1, RestT> | Combs<RestT>
: never
type Modify<T extends string, Candidates extends string[]>
= Candidates extends [infer C1 extends string, ...infer Rest extends string[]]
? `${T} ${C1}` | Modify<T, Rest>
: never
리팩토링
Modify
는 다음과 같이 코드를 줄일 수 있다.
type Modify<T extends string, Candidates extends string[]>
= `${T} ${Candidates[number]}`
이를 Combs
에 바로 적용하면 코드를 더 줄일 수 있다.
type Combs<T extends any[]> = T extends [infer T1 extends string, ...infer RestT extends string[]]
? RestT['length'] extends 0
? never
: `${T1} ${RestT[number]}` | Combs<RestT>
: never
혹시 오류나 개선점이 있다면 댓글 부탁드립니다.
728x90