让你通俗易懂ts中的泛型

一、泛型是什么

大家在聊到泛型的时候,是怎么定义泛型的呢?用来定义函数参数类型返回类型?用来约束接口的?这些都不能完整的回答泛型的概念。官方介绍如下:

软件工程中,我们不仅要创建一致的定义良好的 API,同时也要考虑可重用性。 组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能。

在像 C#和 Java 这样的语言中,可以使用泛型来创建可重用的组件,一个组件可以支持多种类型的数据。 这样用户就可以以自己的数据类型来使用组件。

看了上面一段话是不是更晕了,通俗来说就是在你定义当前的数据类型的时候,并不知道以后调用所需的数据类型,它可以是字符串类型,数组类型,你能想到的任意类型,相当于是一个非常宽泛的类型。

接下说泛型的一些应用,能更加深刻的理解泛型。

二、泛型函数

1
2
3
function person(name: string): string{
return name;
}

上面的代码一下就能看出来是传参需要字符串类型,返回的也是要字符串类型。接下来的代码如下:

1
2
3
function person<T>(name: T): T{
return name;
}

看到符号<>不要犹豫,就是你所了解的泛型,以上代码给函数person做了泛型约束,表述,传入的参数和函数返回的参数都要是用一个类型,当然,你传的是字符串就是得返回字符串类型,传得是数字就得返回数字类型,随便你传什么参数。

1
2
3
4
function person<T, U>(name: T,age: U): [U, T]{
return [age, name]
}
person("foo", 18)

上面函数是定义处理多个函数参数以及函数返回。T,U是你调用的时候传的类型。

1
2
3
4
5
6
interface GetLength {
length: number
}
function person<T>(name: T extends GetLength): T{
return name.length;
}

上面person函数约束参入的参数必须要具有length属性。

三、泛型接口

应用泛型约束接口也是非常常见的一种应用。

1
2
3
4
5
6
interface PersonType<T, U> {
name: T,
age: U
}
const zhangsan: PersonType<string, age> = {name: "zhangsan", age: 16};
const lisi: PersonType<string, age> = {name: "lisi", age: 36};

四、泛型类

1
2
3
4
5
6
7
class OperateArr<T> {
private data: Array<T> = [];
push(item: T): number{
return this.data.push(item)
}
}
const temArr = new Operate<T>()

在实例化的时候传入所需类型即可,这样你下次实例的时候可以改成你想要的任何类型,互相不影响。但是泛型无法约束类的静态(static)成员。