最近准备开始学习 TypeScript 类型体操,没想到第一个 Pick
就被难住了。
Pick 的使用
在 TypeScript 中,Pick
是一个内置的类型工具,用于从一个类型 T
中选择指定的属性 K
,并生成一个新的类型。
在 Pick<T, K>
中,T
是原始类型,K
是一个由 T
的属性名组成的联合类型,表示我们要从 T
中选择哪些属性。
例如,假设有一个类型 Person
:
ts
type Person = {
name: string;
age: number;
gender: string;
};
我们可以使用 Pick
来选择 Person
类型中的部分属性,比如只选择 name
和 age
属性:
ts
type SelectedPerson = Pick<Person, 'name' | 'age'>;
这样,SelectedPerson
类型将只包含 name
和 age
两个属性,而忽略了 gender
属性。
Pick 的实现
Pick
的实现很简单,只需要一行代码,但里面涉及的语法却不少
ts
type MyPick<T, K extends keyof T> = {
[key in K] : T[key]
}
1、keyof
keyof
是 TypeScript 中的一个关键字,用于获取一个类型的所有属性名组成的联合类型。
例如,我们可以使用 keyof
关键字来获取一个类型的所有属性名:
typescript
type Person = { name: string; age: number };
type Keys = keyof Person; // "name" | "age"
在上述例子中,Keys
是一个联合类型,它包含了 Person
类型的所有属性名,即 "name"
和 "age"
。
2、extends
我们都知道 extends
表示继承,但是这里却不是继承的意思,而是泛型约束 。实际上,extends
可以用于约束泛型类型参数、定义类型继承关系和条件类型的判断。
当 extends
用于约束泛型类型参数,例如,T extends SomeType
表示泛型类型参数, T
必须是 SomeType
或其子类型。
3、in
在映射类型中,in
关键字用于遍历一个类型的属性名,并对每个属性进行相应的操作。
例如,我们可以使用 in
关键字将一个类型的所有属性变为可选属性:
typescript
type Person = { name: string; age: number };
type OptionalPerson = { [K in keyof Person]?: Person[K] };
type Result = OptionalPerson; // { name?: string; age?: number; }
在上述例子中,OptionalPerson
是一个映射类型,它遍历 Person
类型的属性名,并将每个属性变为可选属性。
需要注意的是,这里的 K
只是一个占位符,你可以使用任意合法的标识符来代替。例如,可以使用 P
、Prop
等等。
总结
综上,在 Pick
的实现中,我们使用了泛型类型参数 T
和 K
,其中 T
表示原始类型,K
表示要选择的属性名联合类型。我们使用 keyof T
获取 T
的所有属性名组成的联合类型,然后使用 in
关键字进行属性遍历。
在遍历过程中,我们将每个属性名 key
作为索引类型,并使用 T[key]
获取对应属性的类型。最终,我们通过这个遍历过程生成了一个新的类型,该类型包含了 T
中指定属性的类型。