✍ 공부/TypeScript

[type-challenges] Pick

Po_tta_tt0 2023. 5. 16. 14:27
반응형

 

 

 

0. 문제

Pick<T,K>를 쓰지않고 타입 제어하기

type MyPick<T, K extends keyof T> = {
  [key in K] :T[key]
}

/* _____________ Test Cases _____________ */
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
}

/* _____________ Further Steps _____________ */
/*
  > Share your solutions: https://tsch.js.org/4/answer
  > View solutions: https://tsch.js.org/4/solutions
  > More Challenges: https://tsch.js.org
*/

 

 

 

1. 설명

문제를 이해해보자.
MyPick type을 써서 Todo에 있는 title만 뽑아낸 타입을 만들고
MyPick type을 써서 Todo에 있는 title과 completed만 뽑아낸 타입을 만든다.
만약 Todo key에 없는 내용이 들어갔을 때 ('invalid') ts 에러를 발생시킨다.

type MyPick<T, K extends keyof T> = {
  [key in K] :T[key]
}

그러니까 여기서 MyPick은,

  • T(Todo)가 들어오고,
  • K extends keyof T(Todo의 key값으로 이루어진 K)를 받는 타입이다.
  • 이 후 key in K를 이용해 K가 'title'|'completed' 등 여러개를 pick 하는 상황을 고려한다. => key in K = title , key in K = completed 두개 다 통과한다
  • T[key]도 전과 마찬가지. T[title]: string, T[completed]: boolean이 되는 것.

 

 

추가 설명

1.

type name ='a' | 'b'
type TName = {[key in name]:string}

[key in name] : string
에 대해서 좀 더 알아보자

  • key in name -> 'a', 'b' 가 된다
  • 풀어서 말하면 {'a' : string, 'b' : string}이 되는 타입이 생성된 것
  • 결과적으로
    type TName = {
      a: string;
      b: string;
    }
    가 된다.

2.

Expect<Equal<Expected2, MyPick<Todo, 'title' | 'completed'|'noname'>>>

이 예시는 어떻게 될까?
title과 completed는 Todo에 존재하지만, noname은 존재하지 않는다(invalid랑 같은 예시지만..😉)
따라서 typescript는

Type '"title" | "completed" | "noname"' does not satisfy the constraint 'keyof Todo'.
Type '"noname"' is not assignable to type 'keyof Todo'.

라는 에러를 발생시킨다.
typescript😣: keyof Todo에 왜 noname이 있는거야! Todo 안에 있는 key는 title이랑 completed밖에 없어야돼!!
라고 하는 격

반응형