bh2980.dev

4 - Pick

  • #Type Challenges
  • #TypeScript

질문

T에서 K 프로퍼티만 선택해 새로운 오브젝트 타입을 만드는 내장 제네릭 Pick<T, K>을 이를 사용하지 않고 구현하세요.

interface Todo {
  title: string
  description: string
  completed: boolean
}

type TodoPreview = MyPick<Todo, 'title' | 'completed'>

const todo: TodoPreview = {
    title: 'Clean room',
    completed: false,
}

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

type cases = [
  Expect<Equal<Expected1, MyPick<Todo, 'title'>>>,
  Expect<Equal<Expected2, MyPick<Todo, 'title' | 'completed'>>>,
  // @ts-expect-error
  MyPick<Todo, 'title' | 'completed' | 'invalid'>,
]

interface Todo {
  title: string
  description: string
  completed: boolean
}

interface Expected1 {
  title: string
}

interface Expected2 {
  title: string
  completed: boolean
}

선행 지식

keyof T

  1. 객체 타입 T의 모든 프로퍼티 이름을 유니온 타입으로 만든다.

    interface Todo {
      title: string
      description: string
      completed: boolean
    }
    
    keyof Todo
    // 'title' | 'description' | 'completed'

    제네릭 제한

    // @ts-expect-error
    MyPick<Todo, 'title' | 'completed' | 'invalid'>

    코드를 보면 잘못된 key가 들어갈 경우 처음부터 에러를 내도록 기대하고 있다.
    따라서 애초에 넣을 때부터 올바른 키만 받도록 제한을 두어야한다.

    Mapped Type

    {
      [P in K]: ...
    }

    객체 타입을 키 기준으로 반복 생성할 때 사용하는 문법이다.
    K에 들어 있는 각각의 키를 순회하면서, 새로운 객체 타입의 프로퍼티를 만든다.

    인덱스 접근

    T[P]

    객체 타입 T에서 키가 P인 프로퍼티의 타입을 가져올 때 사용한다.

풀이