「这是我参与2022首次更文挑战的第1天,活动详情查看:2022首次更文挑战」。
概述
TypeScript内置了很多实用的工具类型,就是将日常开发中会使用到的类型转换进行了封装,并且可以直接全局进行使用。
通过学习这些工具类型可以帮助我们加深对TS类型系统的了解,并运用到实际开发当中。
Partial(将属性变为可选)
Partial<T> 用于将一个类型的所有属性变为可选的。
源码:
type Partial<T> = {
[P in keyof T]?: T[P];
};
{}就代表是声明为一个字面量对象- 使用
keyof将T类型的key遍历出来,并赋值给P,P作为新的key值 - 通过
T[P]就可以获取到值类型 - 这时再给键后面加上
?就变成可选值了
代码示例:
interface User {
name: string,
age: number
}
// 报错
const user: User = {
}
type User1 = Partial<User>;
// 不报错,因为属性变为可选了
const user1: User1 = {
}
Required(将属性变为必选)
Required<T>用于将一个类型的所有属性都定义为必不可少的。
源代码:
type Required<T> = {
[P in keyof T]-?: T[P];
};
{}就代表是声明为一个字面量对象- 使用
keyof将T类型的key遍历出来,并赋值给P,P作为新的key值 - 通过
T[P]就可以获取到值类型 - 这时再给键后面加上
-?就变成必选值了
代码示例:
interface User {
name: string,
age?: number
}
// 不报错
const user: User = {
name: '金小钗'
}
type User1 = Required<User>;
// 报错,因为所有属性都变为必选了
const user1: User1 = {
name: '金小钗'
}
Readonly(将属性变为只读)
Readonly<T>用于将一个类型的所有属性都定义为只读的。
源代码:
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
{}就代表是声明为一个字面量对象- 使用
keyof将T类型的key遍历出来,并赋值给P,P作为新的key值 - 通过
T[P]就可以获取到值类型 - 这时再给键的前面加上
readonly就变成只读属性了
代码示例:
interface User {
name: string,
age: number
}
const user: User = {
name: '金小钗',
age: 233
}
// 不报错
user.name = '韩立';
type User1 = Readonly<User>;
const user1: User1 = {
name: '金小钗',
age: 233
}
// 报错,因为所有属性都变为只读了
user1.name = '韩立';
Pick(挑选属性作为新类型)
Pick<T, K extends keyof T>可以用来从一个类型中,挑出部分属性来组成一个新的类型。
源代码:
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
- 通过
extends进行限制,K只能由T的键类型组成 {}就代表是声明为一个字面量对象- 使用
in遍历K类型,并赋值给P,P作为新的key值 - 通过
T[P]就可以获取到对应的值类型
代码示例:
interface User {
name: string;
age: number;
}
// 挑选 name 属性组成新的类型
type User1 = Pick<User, 'name'>;
// 报错
const user: User1 = {
name: '金小钗',
age: 233,
};
// 正确,User1 只有 name 属性
const user1: User1 = {
name: '金小钗',
};
Record(创建对象类型)
Record<K extends keyof any, T>可以通过K作为键,T作为值类型来组成一个新的类型。
源代码:
/**
* Construct a type with a set of properties K of type T
*/
type Record<K extends keyof any, T> = {
[P in K]: T;
};
K可以是任意类型。{}就代表是声明为一个字面量对象- 使用
in遍历K类型,并赋值给P,P作为新的key值 - 而
T就作为值类型
示例 1:
interface User {
name: string;
age: number;
}
// 可以用来限定一个对象的键与值的类型
type User1 = Record<string, User>;
const user: User1 = {
jack: {
name: '金小钗',
age: 233,
},
};
示例 2:
// 用来限制类型只能是键值组成的对象
type Obj = Record<string, unknown>;
// 正确
const obj: Obj = {
name: '二愣子'
};
// 报错
const obj1: Obj = [];
Exclude(排除联合类型的部分类型)
Exclude<T, U> = T extends U ? never : T通过条件类型限制,将一个类型中的部分类型进行排除,然后组成一个新的类型。
源代码:
/**
* Exclude from T those types that are assignable to U
*/
type Exclude<T, U> = T extends U ? never : T;
T可以转换成U类型,则返回never类型,否则返回T类型never类型表示永不存在的值的类型,所以相当于将这个类型去除了
代码示例:
在线示例
type T0 = 'a' | 'b' | 'c';
/**
* 排除类型 c
* 此时 T1 的类型相当于 type T1 = "a" | "b"
*/
type T1 = Exclude<T0, 'c'>;
const a:T1 = 'a';
const b:T1 = 'b';
// 报错
const c:T1 = 'c';
Extract(提取联合类型的部分类型)
Extract<T, U>是根据条件排除,而Extract就是与其相反,根据条件提取类型,然后组成一个新的类型。
源代码:
/**
* Extract from T those types that are assignable to U
*/
type Extract<T, U> = T extends U ? T : never;
T可以转换成U类型,则返回T类型,否则返回never类型never类型表示永不存在的值的类型,所以相当于将这个类型去除了- 最后组成的新类型,都是可以转换成
U类型的
代码示例:
在线示例
type T0 = 'd' | 'e' | 'f';
/**
* 提取类型 d 与 e
* 时 T1 的类型相当于 type T1 = "d" | "e"
*/
type T1 = Extract<T0, 'd' | 'e'>;
const d:T1 = 'd';
const e:T1 = 'e';
// 报错
const f:T1 = 'f';