这是我参与8月更文挑战的第27天,活动详情查看:8月更文挑战
泛型简单介绍
真的只是简单介绍,泛型东西可太多、太难了
(1)概念
-
泛型:
-
它是在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定具体类型的一种特性
泛型,顾名思义,即泛指一类类型,在定义时,我们不知道它会接收什么样的类型,会返回什么样的类型
因此,我们用泛型来代替一个具体的类型,相当于一个类型占位符
然后,在使用时才将具体的类型传给我们的定义
-
(2)使用
-
泛型变量
-
在定义时,需要在方法名后面添加尖括号
<>,表示支持一个泛型参数-
如:
<T>,这个T可以是任意指定的
一般情况下,常用的泛型变量可以用这些字母来表示(可以任意指定)
- T
(Type):表示一个 TypeScript 类型 - K
(Key):表示对象中的键类型 - V
(Value):表示对象中的值类型 - E
(Element):表示元素类型
-
-
在使用时,需要将一个具体的类型作为参数传入尖括号中
- 如:
<Number>
- 如:
-
-
泛型函数:
function myFunc1<T>(arg: T): T{ return arg } myFunc1<string>('Ruovan') // Ruovan表示定义一个泛型函数,并将 一个类型 类似于作为参数 传递给这个函数 然后这个函数的 参数和返回值 都会是这个类型
- 它表示的是一个泛指的类型,只有在具体使用这个函数时,才能确定这个类型是什么
// 不仅仅可以传入一个泛型变量,还可以传入多个 function myFunc2<T, X>(arg1: T, arg2: X): T{ return arg1 + arg2 } myFunc2<String, Number>('Ruovan', 24) // Ruovan24 // 或者,可以省略尖括号,会自动做一个类型推断 myFunc2('Ruovan', 24) // Ruovan24 -
泛型接口
- 在接口名后面添加尖括号
- 然后对接口中的属性或者方法定义泛型
// 定义一个泛型接口 interface MyInterface<T> { // 表示参数 arg 的类型 与使用接口时 传进来的类型参数 保持一致 arg1: T; arg2: T } -
泛型类
- 在类名后定义传入的泛型
- 然后对类的属性或方法定义泛型
// 定义一个泛型类 class MyClass<T, A> { arg1: T arg2: A constructor(value1: T, value2: A) { this.arg1 = value1 this.arg2 = value2 } add(): A { return this.arg1 + this.arg2 } } let class = new MyClass<number, string>(24, 'Ruovan'); class.add() / 24Ruovan
(3)泛型约束
-
泛型约束
某种程度上来看,泛型和
any类似,但又不同- 对于
any,你可以传任何类型,并且对你传入的类型的使用都是不会报错的- 即,比如你传入的是
number类型,但使用的是string类型的方法,是无法达到类型检测的效果的
- 即,比如你传入的是
- 对于泛型,你传入了什么类型,就只能使用这个类型的属性或者方法,如果没有,就会报错
- 即,你传入的是
number类型,就只能使用number类型的属性或者方法
- 即,你传入的是
- 所以,在使用泛型时,如果我们想要使用的是具体的某种类型的方法,那么就要对泛型进行约束
-
可以使用
extends来扩展一个含有我们需要的属性或者方法的接口// 1. 先定义一个接口 interface Len { length: number; } // 2. 然后让泛型继承这个接口,表示当前泛型是 由length属性 的一类类型 function myFunc<T extends Len>(arg: T): T{ console.log(arg.length) return arg }通过继承
extends方式来对泛型进行约束,可以传入含有指定属性的类型对于其它类型,则会报错
当然,也可以同时继承多个接口
- 对于
本人前端小菜鸡,如有不对请谅解