본문 바로가기
Language/Typescript

타입챌린지 : 3188-Tuple to Nested Object (medium)

by hsloth 2023. 5. 23.

 

이 글은 제가 타입챌린지를 하면서 해석한 내용을 적는 글입니다. 틀린 내용이 있으면 댓글 달아주시면 감사하겠습니다.

 

https://github.com/type-challenges/type-challenges/blob/main/questions/03188-medium-tuple-to-nested-object/README.md

 

GitHub - type-challenges/type-challenges: Collection of TypeScript type challenges with online judge

Collection of TypeScript type challenges with online judge - GitHub - type-challenges/type-challenges: Collection of TypeScript type challenges with online judge

github.com

 

배열들의 원소를 겹겹이 쌓는 nestedObject를 리턴하는 타입이다.

음.. 생각보다 간단하다. 다만 key를 설정할 때 주의해야한다.

type TupleToNestedObject<T, U> = T extends [...infer O, infer L extends string] ? 
  TupleToNestedObject<O, {[P in L]: U}> : U;
  
  
/* _____________ Test Cases _____________ */
import type { Equal, Expect } from '@type-challenges/utils'

type cases = [
  Expect<Equal<TupleToNestedObject<['a'], string>, { a: string }>>,
  Expect<Equal<TupleToNestedObject<['a', 'b'], number>, { a: { b: number } }>>,
  Expect<Equal<TupleToNestedObject<['a', 'b', 'c'], boolean>, { a: { b: { c: boolean } } }>>,
  Expect<Equal<TupleToNestedObject<[], boolean>, boolean>>,
]

T extends [...infer O, infer L extends string] ? : T을 마지막 원소 L과 나머지 배열 O로 나눈다. 여기서 L이 string이라는 조건이 있어야 key값에 L이 멀쩡히 들어간다.

TupleToNestedObject<O, {[P in L]: U}> : U : T가 L과 O로 나뉜다면, 재귀를 이용한다. 제네릭T 위치에 나머지 배열O를 넣어주고, 제네릭 U의 위치에 {[P in L]: U} 를 넣어준다. [P in L]을 통해 L의 key값을 정의해주면 된다. 그리고 재귀가 끝난다면 U를 리턴한다.

 

여기서 L extends string을 안해주면 key: string 이렇게 나오지 않고 그냥 "key" 이런식으로 결과가 리턴되기 때문에 주의해주어야 한다.