FE/type-challenge

4471. Zip

최토피 2023. 8. 7. 12:47
728x90

문제

In This Challenge, You should implement a type Zip<T, U>, T and U must be Tuple

type exp = Zip<[1, 2], [true, false]> // expected to be [[1, true], [2, false]]

cases

Zip<[1, 2], [true, false]>  // expected to be [[1, true], [2, false]],
Zip<[1, 2, 3], ['1', '2']>  // expected to be [[1, '1'], [2, '2']],
Zip<[], [1, 2, 3]>  // expected to be, [] ,
Zip<[[1, 2]], [3]>  // expected to be [[[1, 2], 3]],

문제 링크


풀이

조건

혹시라도 조건이 잘못 되었다면 댓글 달아주세요… 문제의 설명이 짧아서 주관적으로 해석한겁니다 ㅜ

  1. Zip<T, U>의 T,U 는 any[] 타입이어야 한다.
  2. T[N] 이 비어 있는 경우 더 이상 zip 하지 않는다.
  3. U[N] 이 비어 있는 경우 더 이상 zip 하지 않는다.

정답 - 2가지

첫번째

type Zip<T extends any[], U extends any[]> =
    [T, U] extends [[infer T1, ...infer RestT], [infer U1, ...infer RestU]]
      ? [[T1, U1], ...Zip<RestT, RestU>]
      : []

해설

조건 1을 위해 T, U에 타입 조건을 추가했습니다.

type Zip<T extends any[], U extends any[]> = any

그 후 T,U 에서 순차적으로 각 요소에 접근하기 위해 값이 있는지 확인하는 조건을 추가합니다.

type Zip<T extends any[], U extends any[]> = T extends [infer T1 ...infer RestT] 
    ? U extends [infer U1, ...infer RestU] 
        ? any 
        : any 
    : any

T와 U의 첫 번째 요소는 튜플로 만들고, 남은 RestT와 RestU는 다시 Zip을 진행합니다.

type Zip<T extends any[], U extends any[]> = T extends [infer T1 ...infer RestT] 
    ? U extends [infer U1, ...infer RestU] 
        ? [[T1, U2], ...Zip<RestT, RestU>] 
        : any 
    : any

조건 2와 3을 만족하기 위해서 해당 경우에는 []를 리턴하도록 합니다.

type Zip<T extends any[], U extends any[]> = T extends [infer T1 ...infer RestT] 
    ? U extends [infer U1, ...infer RestU] 
        ? [[T1, U2], ...Zip<RestT, RestU>] 
        : [] 
    : []

리팩토링

두 개의 삼항연산을 하나로 합칩니다.

type Zip<T extends any[], U extends any[]> =
    [T, U] extends [[infer T1, ...infer RestT], [infer U1, ...infer RestU]]
      ? [[T1, U1], ...Zip<RestT, RestU>]
      : []

두번째

type Zip<T extends any[], U extends any[], V extends any[] = []> =
    V['length'] extends T['length'] | U['length']
      ? V
      : Zip<T, U, [...V, [T[V['length']], U[V['length']]]]>

해설

조건 1을 위해 T, U에 타입 조건을 추가했습니다.

type Zip<T extends any[], U extends any[]> = any

조건 2,3은 다음과 같은 하나의 조건으로 만들 수 있습니다. T와 U 중 더 작은 길이만큼만 Zip을 진행한다. 따라서 다음과 같이 이전 기록들을 담아둘 V 인자를 추가해서, 둘 중 작은 배열만큼만 진행하도록 할 수 있습니다.

type Zip<T extends any[], U extends any[], V extends any[] = []> =
	V['length'] extends T['length'] | U['length'] 
    	? V 
        : []

V의 길이가 0에서부터 시작하므로, V의 길이에 해당하는 T,U의 요소를 가져와서 넣어줄 수 있습니다.

type Zip<T extends any[], U extends any[], V extends any[] = []> =
    V['length'] extends T['length'] | U['length']
      ? V
      : Zip<T, U, [...V, [T[V['length']], U[V['length']]]]>

 


혹시나 설명 중 오류가 있으면 언제든지 댓글, 피드백 부탁드리겠습니다!

728x90