본문 바로가기
Language/Typescript

타입챌린지 : 527-Append to object (medium)

by hsloth 2023. 4. 7.

 

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

 

https://github.com/type-challenges/type-challenges/blob/main/questions/00527-medium-append-to-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

 

객체에 key: value 한 쌍을 뒤에 추가하는 타입이다.

 

나의 첫 번째 답을 봐보자.

// 오답
type AppendToObject<T extends object, U extends string, V> = {
  [P in keyof T]: T[P];
} & {
  [P in U]: V;
}

음... 그냥 아니었다. 타입자체가 intersection 타입이라 그런 것 같다. 아무래도 {} 안에 한 번에 넣어야 하는 것 같다.

 

 

그러다 문득, Record를 써서 해볼수는 없을까? 라는 생각이 들어서 다음 코드를 작성해보았다.

type AppendToObject<T extends object, U extends string, V> = Record<keyof T | U, V>

여기서, 유니온 타입에 대한 힌트를 얻었다.

"key값에다가 유니온 타입으로 keyof T | U 로 하면 key값을 한 번에 설정할 수 있지 않을까?"라는 생각이 들어 다음 코드를 작성했다.

 

// 정답
type AppendToObject<T extends object, U extends string, V> = {
  [P in (keyof T) | U]: P extends keyof T ? T[P] : V;
}

/* _____________ Test Cases _____________ */
import type { Equal, Expect } from '@type-challenges/utils'

type test1 = {
  key: 'cat'
  value: 'green'
}

type testExpect1 = {
  key: 'cat'
  value: 'green'
  home: boolean
}

type test2 = {
  key: 'dog' | undefined
  value: 'white'
  sun: true
}

type testExpect2 = {
  key: 'dog' | undefined
  value: 'white'
  sun: true
  home: 1
}

type test3 = {
  key: 'cow'
  value: 'yellow'
  sun: false
}

type testExpect3 = {
  key: 'cow'
  value: 'yellow'
  sun: false
  isMotherRussia: false | undefined
}

type cases = [
  Expect<Equal<AppendToObject<test1, 'home', boolean>, testExpect1>>,
  Expect<Equal<AppendToObject<test2, 'home', 1>, testExpect2>>,
  Expect<Equal<AppendToObject<test3, 'isMotherRussia', false | undefined>, testExpect3>>,
]

[P in (keyof T) | U]: P extends keyof T ? T[P] : V; T의 key값과 U를 key P라고 정의하고, P가 T의 key이면, T[P]를 리턴하고, 아니라면(P가 U라면) V를 리턴한다.