728x90
문제
Construct a tuple with a given length.
type result = ConstructTuple<2> // expect to be [unknown, unkonwn]
cases
type cases = [
Expect<Equal<ConstructTuple<0>, []>>,
Expect<Equal<ConstructTuple<2>, [unknown, unknown]>>,
Expect<Equal<ConstructTuple<999>['length'], 999>>,
Expect<Equal<ConstructTuple<1000>['length'], 1000>>,
]
정답
type ConstructTuple<L extends number, Answer extends unknown[] = [], S extends string = `${L}`> =
S extends `${infer S1 extends string}${infer Rest}`
? ConstructTuple<L, AddNTime<S1, Answer>, Rest>
: Answer
type AddNTime<N extends string, A extends unknown[] = [], Counter extends any[] = []> =
`${Counter['length']}` extends N
? Multiple10<A>
: [...AddNTime<N, A, [...Counter, 0]>, unknown]
type Multiple10<N extends unknown[], Count extends any[] = []> =
Count['length'] extends 9 ? N : [...Multiple10<N, [...Count, 0]>, ...N]
풀이
조건
- 입력
L
만큼의 길이를 가진 unknown 배열을 출력해야 한다.
해설
L
만큼 재귀로 돌면서 배열을 만드는 로직을 구현한다.
type ConstructTuple<L extends number, Answer extends unknown[] = []> =
Answer['length'] extends L ? Answer : ConstructTuple<L, [...Answer, unknown]>
정상적으로 동작하지만, L
이 1000이상이 되는 경우, 재귀를 너무 많이 돌아 error를 표기한다.
다른 접근이 필요한데, 다음과 같은 접근법을 사용할 수 있다.
101의 경우
- (10) = 1 * 10
- 101 = (10) * 10 + 1 = (1 * 10) * 10 + 1
와 같이 자리수를 넘어가며 10을 곱한 만큼의 배열을 생성하는 방법으로 접근할 수 있다.
type ConstructTuple<L extends number, Answer extends unknown[] = [], S extends string = `${L}`> =
S extends `${infer S1 extends string}${infer Rest}`
? ConstructTuple<L, AddNTime<S1, Answer>, Rest>
: Answer
type AddNTime<N extends string, A extends unknown[] = [], Counter extends any[] = []> =
`${Counter['length']}` extends N
? Multiple10<A>
: [...AddNTime<N, A, [...Counter, 0]>, unknown]
type Multiple10<N extends unknown[], Count extends any[] = []> =
Count['length'] extends 9 ? N : [...Multiple10<N, [...Count, 0]>, ...N]
Multiple10
은 입력으로 온 값을 10배 길이의 배열로 출력하는 타입이다.
AddNTime
은A
에다가N
개의 unknown을 배열에 추가해서 출력하는 타입이다.
ConstructTuple
는L
을 앞자리에서부터 돌면서 배열을 늘려가기 시작한다.
오류나 개선점이 있다면 댓글 부탁드리겠습니다
728x90
'FE > type-challenge' 카테고리의 다른 글
3. Omit (0) | 2023.08.31 |
---|---|
2. ReturnType (0) | 2023.08.30 |
5360. Unique (0) | 2023.08.25 |
5821. MapTypes (0) | 2023.08.24 |
5317. LastIndexOf (0) | 2023.08.21 |