开始准备做题环境
在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