一、泛型
泛型程序设计(generic programming)是程序设计语言的一种风格或范式
泛型允许我们在强类型程序设计语言中编写代码时使用一些以后才指定的类型,在实例化时作为参数指明这些类型 在typescript中,定义函数,接口或者类的时候,不预先定义好具体的类型,而在使用的时候在指定类型的一种特性
二、使用方式
泛型通过<>的形式进行表述,可以声明:
- 函数
- 接口
- 类
函数声明
声明函数的形式如下:
定义泛型的时候,可以一次定义多个类型参数,比如我们可以同时定义泛型 T 和 泛型 U:
接口声明
声明接口的形式如下:
那么当我们想传入一个 number 作为参数的时候,就可以这样声明函数:
类声明
使用泛型声明类的时候,既可以作用于类本身,也可以作用与类的成员函数
下面简单实现一个元素同类型的栈结构,如下所示:
使用方式如下:
如果上述只能传递
string 和 number 类型,这时候就可以使用 <T extends xx> 的方式猜实现约束泛型,如下所示:
多类型约束
泛型的类型变量可以有多个,并且类型变量之间还可以约束(比如,第二个类型变量受第一个类型变量约束)。 比如创建一个函数来获取对象中属性的值:
解释:
1、添加了第二个类型变量 key,两个类型变量之间使用 (,) 逗号分隔
2、keyof 关键字接受一个对象类型,生成其键名(可能是字符串或数字)的联合类型
3、上面示例中 keyof Type 实际上获取的是 person 对象所有键的联合类型,也就是:'name'|'age'
4、类型变量 key 受 Type 约束,可以理解为:key只能是 Type 所有键中的任意一个,或者说只能访问同对象中存在的属性
函数实参的第一个可以是字符串、数组、对象、数字等 如果是数字的话,第二个参数就是数值的一些方法
如果是字符串的话,第二个参数可以是number 或者字符串的一些方法,如果是 number 的话代表索引
如果是数组的话,第二个参数就是数组的一些属性和方法
泛型接口
泛型接口:接口也可以配合泛型来使用,以增加其灵活性,增强其复用性
解释:
1、在接口名称后面添加 <类型变量>,那么这个接口就变成了泛型接口
2、接口的类型变量,对接口中所有其它成员可见,也就是接口中所有成员都可以使用类型变量
3、使用泛型接口时,需要显示指定具体的类型(比如,此处的 IdFunc)
4、此时,id方法的参数和返回值类型都是 number;ids方法的返回值类型时 number[]
实际上,JS中的数组在TS中就是一个泛型接口
解释: 当我们在使用数组时,TS 会根据数组的不同类型,来自动将类型变量设置为相应的类型
技巧: 可以通过 Ctrl + 鼠标左键 (Mac:option+鼠标左键)来查看具体的类型信息
泛型工具类型:
TS 内置了一些常用的工具类型,来简化 TS 中的一些常见操作
说明:它们都是基于泛型实现的(泛型适用于多种类型,更加通用),并且是内置的,可以直接在代码中使用
这些工具类型有很多,主要的:
1、Partial < Type >
它用来构造(创建)一个类型,将Type的所有属性设置为可选
解释:构造出来的新类型 PartialProps 结构 和 props 相同,但所有属性都变为可选的
2、Readonly< Type >
它用来构造一个类型,将Type 的所有属性都设置为 readonly(只读)
解释:构造出来的新类型ReadonlyProps 结构和props相同,但所有属性都变为只读的
当我们想重新给 id 属性赋值时,就会报错:无法为 "id"赋值,因为它是只读属性
3、Pick<Type,keys> 它从 Type 中选择一组属性来构造新类型
解释:
1、Pick 工具类型有两个类型变量:1)表示选择谁的属性、2)表示选择哪几个属性
2、其中第二个类型变量,如果只选择一个则只传入该属性名即可
3、第二个类型变量传入的属性只能是第一个类型变量中存在的属性
4、构造出来的新类型 PiceProps,只有 id 和 title 两个属性类型
4、Record<keys,Type>
它构造一个对象属性,属性值为 Keys,属性类型为 Type
解释:
1、Record 工具类型有两个类型变量:1)表示对象有哪些属性,2)表示对象属性的类型
2、构建的新对象类型 RecordObj 表示:这个对象有三个属性分别为a/b/c,属性值的类型都是 string[]