[Type Challenge][easy] Tuple to Object

곰개구리·2023년 12월 28일
0

type challenge

목록 보기
4/4

개요

배열(튜플)을 받아, 각 원소의 값을 key/value로 갖는 오브젝트 타입을 반환하는 타입을 구현하세요.

예시:

const tuple = ['tesla', 'model 3', 'model X', 'model Y'] as const

type result = TupleToObject<typeof tuple> // expected { tesla: 'tesla', 'model 3': 'model 3', 'model X': 'model X', 'model Y': 'model Y'}

/* _____________ 여기에 코드 입력 _____________ */

type TupleToObject<T extends readonly any[]> = any

/* _____________ 테스트 케이스 _____________ */
import type { Equal, Expect } from '@type-challenges/utils'

const tuple = ['tesla', 'model 3', 'model X', 'model Y'] as const
const tupleNumber = [1, 2, 3, 4] as const
const sym1 = Symbol(1)
const sym2 = Symbol(2)
const tupleSymbol = [sym1, sym2] as const
const tupleMix = [1, '2', 3, '4', sym1] as const

type cases = [
  Expect<Equal<TupleToObject<typeof tuple>, { tesla: 'tesla', 'model 3': 'model 3', 'model X': 'model X', 'model Y': 'model Y' }>>,
  Expect<Equal<TupleToObject<typeof tupleNumber>, { 1: 1, 2: 2, 3: 3, 4: 4 }>>,
  Expect<Equal<TupleToObject<typeof tupleSymbol>, { [sym1]: typeof sym1, [sym2]: typeof sym2 }>>,
  Expect<Equal<TupleToObject<typeof tupleMix>, { 1: 1, '2': '2', 3: 3, '4': '4', [sym1]: typeof sym1 }>>,
]

// @ts-expect-error
type error = TupleToObject<[[1, 2], {}]>

해석

  • 두 가지 조건에서 모두 에러가 나지 않아야 한다
  1. 아래 조건에서 타입이 일치해야 함
type cases = [
  Expect<Equal<TupleToObject<typeof tuple>, { tesla: 'tesla', 'model 3': 'model 3', 'model X': 'model X', 'model Y': 'model Y' }>>,
  Expect<Equal<TupleToObject<typeof tupleNumber>, { 1: 1, 2: 2, 3: 3, 4: 4 }>>,
  Expect<Equal<TupleToObject<typeof tupleSymbol>, { [sym1]: typeof sym1, [sym2]: typeof sym2 }>>,
  Expect<Equal<TupleToObject<typeof tupleMix>, { 1: 1, '2': '2', 3: 3, '4': '4', [sym1]: typeof sym1 }>>,
]
  1. 아래 조건에서 타입이 일치하지 않아야 함
// @ts-expect-error
type error = TupleToObject<[[1, 2], {}]>

아이디어

  1. 즉, 타입은 동일한 key / value쌍으로 이루어진 타입이다.
  1. 즉, 타입의 key는 string, number, symbol만으로만 이루어져 있어야 한다.

풀이

1. 타입은 동일한 key / value쌍으로 이루어진 타입이다.

type TupleToObject<T extends readonly any[]> = {
  [P in T[number]]: p
}

위 풀이를 사용할 경우 하단의

// @ts-expect-error
type error = TupleToObject<[[1, 2], {}]>

에서 error가 발생하지 않는다

  • any[] 으로 이루어져 있어 [[1, 2], {}] 와 같은 값이 들어올 때 에러를 발생시키지 않는 것

2. 타입의 key는 string, number, symbol만으로만 이루어져 있어야 한다.

type TupleToObject<T extends readonly (string | number | symbol)[]> = {
  [P in T[number]]: p
}
  • key 값의 type을 string | number | symbol 로 제한한다
    • 위 방법을 통해
      // @ts-expect-error
      type error = TupleToObject<[[1, 2], {}]>
      에서 에러를 발생시킨다

결과 코드

/* _____________ 여기에 코드 입력 _____________ */

type TupleToObject<T extends readonly (string | number | symbol)[]> = {
  [P in T[number]] : P
}

/* _____________ 테스트 케이스 _____________ */
import type { Equal, Expect } from '@type-challenges/utils'

const tuple = ['tesla', 'model 3', 'model X', 'model Y'] as const
const tupleNumber = [1, 2, 3, 4] as const
const sym1 = Symbol(1)
const sym2 = Symbol(2)
const tupleSymbol = [sym1, sym2] as const
const tupleMix = [1, '2', 3, '4', sym1] as const

type cases = [
  Expect<Equal<TupleToObject<typeof tuple>, { tesla: 'tesla', 'model 3': 'model 3', 'model X': 'model X', 'model Y': 'model Y' }>>,
  Expect<Equal<TupleToObject<typeof tupleNumber>, { 1: 1, 2: 2, 3: 3, 4: 4 }>>,
  Expect<Equal<TupleToObject<typeof tupleSymbol>, { [sym1]: typeof sym1, [sym2]: typeof sym2 }>>,
  Expect<Equal<TupleToObject<typeof tupleMix>, { 1: 1, '2': '2', 3: 3, '4': '4', [sym1]: typeof sym1 }>>,
]

// @ts-expect-error
type error = TupleToObject<[[1, 2], {}]>

알게 된 것

type TupleToObject<T extends readonly (string | number | symbol)[]> = {
  [P in T[number]] : P
}

위 코드에서 T[number] 와 같이 사용 할 경우 T의 각 인덱스의 요소를 순회하면서 type으로 사용 가능하다.

예를 들어...

const students = ['hana', 'maple', 'jordan', 'rily'] 

일 때

type MyType<T extends (string | number | symbol)[]> = {
  [P in T[number]]: P
}

const data: MyType<string[]> = {'a': 'a', 'b': 'b'}

위와 같이 사용 가능한 것!

profile
개굴개굴 곰개굴

0개의 댓글