본문 바로가기

FE/type-challenge

5821. MapTypes

728x90

문제

Implement MapTypes<T, R> which will transform types in object T to different types defined by type R which has the following structure

type StringToNumber = {
  mapFrom: string; // value of key which value is string
  mapTo: number; // will be transformed for number
}

cases

type cases = [
  Expect<Equal<MapTypes<{ stringToArray: string }, { mapFrom: string; mapTo: [] }>, { stringToArray: [] }>>,
  Expect<Equal<MapTypes<{ stringToNumber: string }, { mapFrom: string; mapTo: number }>, { stringToNumber: number }>>,
  Expect<Equal<MapTypes<{ stringToNumber: string; skipParsingMe: boolean }, { mapFrom: string; mapTo: number }>, { stringToNumber: number; skipParsingMe: boolean }>>,
  Expect<Equal<MapTypes<{ date: string }, { mapFrom: string; mapTo: Date } | { mapFrom: string; mapTo: null }>, { date: null | Date }>>,
  Expect<Equal<MapTypes<{ date: string }, { mapFrom: string; mapTo: Date | null }>, { date: null | Date }>>,
  Expect<Equal<MapTypes<{ fields: Record<string, boolean> }, { mapFrom: Record<string, boolean>; mapTo: string[] }>, { fields: string[] }>>,
  Expect<Equal<MapTypes<{ name: string }, { mapFrom: boolean; mapTo: never }>, { name: string }>>,
  Expect<Equal<MapTypes<{ name: string; date: Date }, { mapFrom: string; mapTo: boolean } | { mapFrom: Date; mapTo: string }>, { name: boolean; date: string }>>,
]

문제 링크

정답

type MapTypes<T extends object, R extends { mapFrom: any; mapTo: any }> = {
  [key in keyof T]: T[key] extends R['mapFrom']
    ? R extends { mapFrom: T[key] }
      ? R['mapTo']
      : never
    : T[key]
}

풀이

조건

  1. 첫 번째 인자 T의 value값이 두 번째 인자 R의 mapFrom 인 경우에 mapTo로 바꾼다.
  1. T의 value를 모두 확인했다면, 바뀐 object를 출력한다.

해설

T의 key를 순회하여, value가 mapFrom에 해당하는 요소는 mapTo로 변경한다

type MapTypes<T extends object, R extends { mapFrom: any; mapTo: any }> = {
  [key in keyof T]: T[key] extends R['mapFrom'] ? R['mapTo'] : T[key]
}

대부분의 케이스는 통과하지만, 마지막 케이스를 통과하지 못한다.

문제가되는 두 번째 인자가 Union 타입이므로, 각 항목에 맞는지 확인하는 로직을 추가한다.

type MapTypes<T extends object, R extends { mapFrom: any; mapTo: any }> = {
  [key in keyof T]: T[key] extends R['mapFrom']
    ? R extends { mapFrom: T[key] }
      ? R['mapTo']
      : never
    : T[key]
}

 


혹시나 오류나 개선점이 있다면 댓글 부탁드려요

728x90

'FE > type-challenge' 카테고리의 다른 글

7544. ConstructTuple  (0) 2023.08.26
5360. Unique  (0) 2023.08.25
5317. LastIndexOf  (0) 2023.08.21
5310. Join  (0) 2023.08.18
5153. IndexOf  (0) 2023.08.17