何为Pick?

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

就是从一个复合类型中,取出几个想要的类型的组合,例如:

// 原始类型
interface TState {
	name: string;
	age: number;
	like: string[];
}
// 如果我只想要name和age怎么办,最粗暴的就是直接再定义一个(我之前就是这么搞得)
interface TSingleState {
	name: string;
	age: number;
}
// 这样的弊端是什么?就是在Tstate发生改变的时候,TSingleState并不会跟着一起改变,所以应该这么写
interface TSingleState extends Pick<TState, "name" | "age"> {};

写到这里,Pick的用法就写完了,但是会有个疑问,extends不是用来继承的么?那为什么可以写在泛型里?有没有人跟我一样的疑惑?
我去查了资料后发现,还是官方文档中有这个解释(所以还是要多看文档,官方文档大多数比外面写的好得多),以下这段内容来自于官方文档。

泛型约束《官方文档传送门

你应该会记得之前的一个例子,我们有时候想操作某类型的一组值,并且我们知道这组值具有什么样的属性。 在 loggingIdentity例子中,我们想访问arg的length属性,但是编译器并不能证明每种类型都有length属性,所以就报错了。

function loggingIdentity<T>(arg: T): T {
    console.log(arg.length);  // Error: T doesn't have .length
    return arg;
}

相比于操作any所有类型,我们想要限制函数去处理任意带有.length属性的所有类型。 只要传入的类型有这个属性,我们就允许,就是说至少包含这一属性。 为此,我们需要列出对于T的约束要求。

为此,我们定义一个接口来描述约束条件。 创建一个包含 .length属性的接口,使用这个接口和extends关键字来实现约束:

interface Lengthwise {
    length: number;
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
    console.log(arg.length);  // Now we know it has a .length property, so no more error
    return arg;
}

现在这个泛型函数被定义了约束,因此它不再是适用于任意类型:

loggingIdentity(3);  // Error, number doesn't have a .length property

我们需要传入符合约束类型的值,必须包含必须的属性:

loggingIdentity({length: 10, value: 3});

---------------------------------文档结束--------------------------------------
这是找到的唯一一处跟我的问题比较吻合的答案了,至此我们直到了在泛型中使用extends并不是用来继承的,而是用来约束类型的。所以这个K extends keyof T,应该是说key被约束在T的key中,不能超出这个范围,否则会报错的。
不知道你们理解了么~如果没有理解的话,可以留言告诉我,我们再讨论讨论。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐