类型体操系列之实现Pick

大家好,我是初心,本篇是我坚持原创文章的第02期文章,如有错误,欢迎指正👏🏻

TS现状

介绍类型体操之前,容我讲个笑话,其实我一直在内卷TypeScript,却未尝试过项目实战,学了忘,忘了又学,一直循环;

后面无意发现了TS有类型体操,预期是想通过类型体操深入学习TS,打破目前困局。

什么是类型体操

那么什么是类型体操呢,类型体操来源 type-challenges 项目,其意在于更好的了解 TS 的类型系统,编写自己的类型工具,也有种只是单纯的享受挑战的乐趣!

type-challenges 的高质量类型可以提高项目的可维护性并避免一些潜在的漏洞。

知道了什么是类型体操,让我们正式开始吧。

题目介绍

实现 Pick

实现 TS 内置的 Pick<T, K>,但不可以使用它。

从类型 T 中选择出属性 K ,构造成一个新的类型

例如:

// 通过interface 定义了 Todo
interface Todo {
  title: string
  description: string
  completed: boolean
}

// 挑选出 title 和 completed
type TodoPreview = MyPick<Todo, 'title' | 'completed'>

const todo: TodoPreview = {
    title: '云层上的光',
    completed: false,
}

例子中interface定义了三个属性并定义了类型,MyPick从中挑选出 titlecompleted,这样 todo 声明的变量就必须是titlecompleted且类型分别是 字符串和布尔类型。

解题思路

熟悉Pick的童鞋对于这道题简直就是so一贼,不熟悉的童鞋也不要紧,Pick其实是 TS 内置方法,Pick的作用就是从一个对象中挑选需要的字段出来,比如从Todo里面只取出titlecompleted

在没有实现 Pick我们可以这样处理,重新声明一个新的类型

interface TodoPreviewType{
	title: string
  completed: boolean
}

这样做的好处确实可以解决这个问题,但是类型体操是让我们实现MyPick

MyPick实现

讲实话,初次接触类型体操,即使我有学习过TS可是还是做不出来,所以我们看看Issues的实现

type Pick<T, K extends keyof T> = {
    [P in K]: T[P];
};

短短的3行代码就实现了TS内置的Pick,简直是不可思议。

TS中keyof、extends、in原理

首先我们看看上文中keyofextendsin在TS中分别代表着什么含义?

keyof原理

TS 中的keyof的作用等价于 JS 中的Object.keys

// keyof
interface Person {
    name: string;
    age: number;
    gender: string;
}
// 此时的 P 就是一个联合类型
type P = keyof Person; // "name" | "age" | "gender"
extends原理

TS 中的extends有2个作用,第1个是继承 第2个是判断

// 第一种 继承
interface Person{
  name: string;
  age: number;
}

// A 继承了 Person 所有的类型
interface A extends Person{
  gender: string;
}

// 第二种 判断
interface B{
  name: string;
}
// 判断 B 是否 >= Person 也就是说 B的类型必须要多余或者等于  Person 才会是 true
type b = B extends Person ? true: false;// b ===  false
// 判断 1 是否是 number 类型
type isNnumber = 1 extends number ? true : false;
in原理

TS 中 in 其实和 JS 中的 in 用法一致,作用类似JS中的for…in或者for…of

MyPick实现原理

// MyPick实现原理
type MyPick<T, K extends keyof T> = {
    [P in K]: T[P];
};
  • 目光聚集在泛型中 <T, K extends keyof T> 此时的T代表的是谁呢?K 又代表的谁呢
  • 在使用中我们可以看到type TodoPreview = MyPick<Todo, 'title' | 'completed'>
  • 显而易见 T 其实就是 Todo。 K的话其实就是联合类型 ‘title’ | ‘completed’
  • 那么 k extends keyof T 检测 K是否符合 Todo 的类型
  • [P in K]: T[P]左边为循环,其中P就是循环的key,K则是联合类型(title | completed) 解析起来就是 [key in (‘title’ | ‘completed’)] : Todo[key]
  • 至此MyPick就算结束了。

总结

Pick 从一个对象中挑选需要的字段出来,挑选出来的字段取决于第二个参数。

  • 20
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值