banner和cover图片出处
前言
记录最近重构公司一个项目的时候,对ts工具类型的一些学习,高效的使用好ts的类型推导
正文
- 关于什么是工具类型,就是通过一些操作对静态描述的类型结构进行增删改查、或者挑选在聚合组成一个新的类型声明的操作;社区也有很多类似的工具类型的库,这些工具类型就相当于类型声明的 lodash。
- 一些后文会提到的基本概念
关于any、unknown、never区别
相同
三者都是ts的类型声明
不同
- any:ts中的顶层类型,包含js中的所有值(任何类型的值),但是用他声明的变量,会失去编译器带来的类型推导、提示等,会使的ts的本身意义失效
- unknown:和any类似,但是不同的是,编译器不允许使用他声明的变量调用任何函数,除非在调用之前做类型判断,不然会报错
- never:ts底层类型,和前两者完全相反,表示不包含任何值,可以用在一些没有返回值的函数等
关于type 和 interface区别
相同
均可以用来定义 接口 结构,且都可以继承和互相继承,只是写法不太一样
不同
- type 可以声明 基本类型别名,interface 不可以
- type 可以声明 联合类型, interface 不可以
- type 可以声明 元祖类型,interface 不可以
- type 可以通过 typeof 声明类型,interface 不可以
- interface 同名会自动合并,type 会报错
关于泛型
泛型 是一切工具类型的基础,所有的工具类型基本都是基于泛型来实现
什么是泛型呢,泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性,使接口,函数或类更加通用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| export interface People<T = any> { name: string; age: number; sex: SEX; customInfo?: T; bodyInfo: { height: number; weight: number; }; }
const demo: Partial< People2<{ address?: string; }> > = {};
|
ts内置工具类型
ts,本身内置了一些基本的工具类型共日常使用,然后也可以结合这些自定义自己实际场景需要的一些工具类型。
Pick
选中指定类型中的一个或多个类型构建一个新类型
| enum SEX { MAN = "MAN", WOMAN = "WOMAN", }
export interface People { name: string; age: number; sex: SEX; bodyInfo: { height: number; weight: number; }; }
type BaseInfo = Pick<People, "name" | "age" | "sex">;
|
获取指定类型的某个类型
类似js字面量对象一样的访问语法,和 pick 的区别是这样操作得到的是单个指定的类型,pick 会把拿到的类型放到一个 interface 中
| enum SEX { MAN = "MAN", WOMAN = "WOMAN", } export interface People { name: string; age: number; sex: SEX; bodyInfo: { height: number; weight: number; }; }
type BodyInfo = People["bodyInfo"];
|
Omit
和pick用法一样,作用是忽略指定的单个或多个类型,然后把剩余的类型构建为一个新的类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| enum SEX { MAN = "MAN", WOMAN = "WOMAN", }
export interface People { name: string; age: number; sex: SEX; bodyInfo: { height: number; weight: number; }; }
type Dog = Omit<People, "bodyInfo" | "sex">;
const dog: Dog = { name: "dog", age: 100, };
|
Partial
把所有类型转为可选
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| enum SEX { MAN = "MAN", WOMAN = "WOMAN", }
export interface People { name: string; age: number; sex: SEX; bodyInfo: { height: number; weight: number; }; }
export interface Man extends Partial<People> { sex: SEX.MAN; }
|
Required
和Partial用法一致,作用相反,把所有类型转为必选
| export interface People { name: string; age: number; sex: SEX; bodyInfo: { height: number; weight: number; }; }
type _People = Partial<People>;
type Req_People = Required<_People>;
|
Record
声明字面量对象类型
| const obj: Record<string, any> = {};
|
Readonly
设置所有类型为只读
| enum SEX { MAN = "MAN", WOMAN = "WOMAN", } export interface People { name: string; age: number; sex: SEX; bodyInfo: { height: number; weight: number; }; }
type Man = Readonly<People>;
|
Exclude
当第一个类型不是第二个类型的子类型时,直接返回第一个类型或者never
和exclude相反
开源ts工具类型合集
除过自己写,社区有一些已经类似lodash一样,封装了常用的一些工具类型: