Type-challenges项目挑战题

305 阅读2分钟

开始准备做题环境

在vscode中插件市场搜索Type Challenges插件 安装该插件 安装完成后在vscode左侧侧边栏中会出现<T>符号 点击图标就会显示出项目题库**(最好是能科学上网因为 题目的答案是在github上 方便复盘参考)**

第一题

不使用 ReturnType 实现 TypeScript 的 ReturnType<T> 泛型。

例如:

const fn = (v: boolean) => {
  if (v)
    return 1
  else
    return 2
}

type a = MyReturnType<typeof fn> // 应推导出 "1 | 2"
                      
  解题思路:
          1. 首先需要确定fn是个函数  所以  fn extends Function
          2..其次是他是个接受一个参数返回一个参数的函数 (...reset:any[])=>infer P 
          3.判断fn是不是这个函数 fn extends  (...reset:any[])=>infer P ? P: never
		4.这里可能有帖子不明白为什么要使用infer,应为需要保证类型的可拓展性,假如函数返回的是个字符					串,infer也能进行类型推导

最终结果: MyReturnType<T> = fn extends  (...reset:any[])=>infer P ? P: never

第二题

不使用 Omit 实现 TypeScript 的 Omit<T, K> 泛型。

Omit 会创建一个省略 K 中字段的 T 对象。

例如:

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

type TodoPreview = MyOmit<Todo, 'description' | 'title'>

const todo: TodoPreview = {
  completed: false,
}

解题思路:
	1.分析MyOmit会要传两个类型 一个是接口类型一个是联合类型 分别使用 T K来代替
        MyOmit<T,K>
     2.需要省略K类型字段  [P in keyof  T as P extends K?never:P]:T[P]
	3.需要是个对象
  
  结果:
 MyOmit<T,K> = {[P in keyof  T as P extends K?never:P]:T[P]}

第三题

不使用 Pick<T, K> ,实现 TS 内置的 Pick<T, K> 的功能。

从类型 T 中选出符合 K 的属性,构造一个新的类型。

例如:

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

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

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

解题思路:
	1.其实和第二题一样的思路 一个是筛选相同属性 一个是筛选不同属性
  
  结果:
 MyPick<T,K> = {[P in keyof T as P extends K ? P : never]:T[P]}

第四题

实现泛型GetReadonlyKeys<T>GetReadonlyKeys<T>返回由对象 T 所有只读属性的键组成的联合类型。

例如:


 type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false

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

type Keys = GetReadonlyKeys<Todo> // expected to be "title" | "description"

解题思路:
1.需要三个泛型 T K U  
GetReadonlyKeys<T, K extends Readonly<T> = Readonly<T>,U extends keyof T = keyof T >
  T表示接口类型    K表示所有属性都为只读的接口类型  U表示接口属性的联合类型
  2.通过提供额的Equal类型来判断类型是否是只读
  
  结果:
GetReadonlyKeys<T, K extends Readonly<T> = Readonly<T>,U extends keyof T = keyof T >= U extends keyof T ?
  Equal<Pick<T,U>,Pick<K,U>> extends true? U:never:never