题目

实现 TS 内置的 Pick,但不可以使用它。
从类型 T 中选择出属性 K,构造成一个新的类型

  1. interface Todo {
  2. title: string
  3. description: string
  4. completed: boolean
  5. }
  6. type TodoPreview = MyPick<Todo, 'title' | 'completed'>
  7. const todo: TodoPreview = {
  8. title: 'Clean room',
  9. completed: false,
  10. }

单元测试

import { 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
}

通过 JS 解题

function myPick (todo, keys) {
  const obj = {};
  keys.forEach(key => {
    if(key in todo){
          obj[key] = todo[key];
    }
  });

  return obj;
}

知识点

  1. 返回一个对象
  2. 遍历 foreach
  3. todo[key] 取值
  4. 看看 key 在不在 todo 里面

    翻译为 TS

    type MyPick<T, K extends keyof T> = {
     [P in K] = T[P];
    };
    
  5. 返回一个对象

  • = {}
  1. 遍历 foreach
  • P in K
  1. todo[key] 取值
  • T[P]
  1. 看看 key 在不在 todo 里面
  • keyof

union 联合类型

  • K extends keyof T
  • 增加约束 Constraints