TypeScript学习第七篇 - 泛型

时间:2023-02-09 12:01:02


1. 泛型的定义;

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

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

在TypeScript中,我们可以使用 any 类型来让函数返回多种类型,比如一个函数既可以返回 string 类型,也可以返回 number 类型,这样虽然实现了支持多种类型的数据,但是却放弃了类型检查,可能会导致传入的类型与返回的类型不一致。

为此,TypeScript中的泛型就是解决类、接口方法的复用性、以及对不特定数据类型的支持(类型校验)。

2. 泛型函数;

// T表示泛型,具体什么类型是调用这个方法的时候决定的。
function getData<T>(value:T):T{
return value;
}
getData<number>(123456);
// OK

// getData<number>('123456');
// 报错


// 如果返回的数据不确定类型,可以改成any类型,只对传参类型进行约束就可以了。
function getAnyData<T>(value:T):any{
return value;
}

3. 泛型类;

定义一个函数,求最小堆算法,需要同时支持返回数字与字符类型。

class MinClass <T>{
public list:T[]=[];
add(value:T):void{
this.list.push(value);
}
min():T{
var minNum = this.list[0];
for(var i = 0;i<this.list.length;i++){
if(minNum >this.list[i]){
minNum = this.list[i];
}
}
return minNum;
}
}
// 实现化时声明了类型,后续传入的参数只能是数字
var num = new MinClass<number>();

num.add(1);
// OK

// num.add('2');
// 报错

4. 泛型接口;

对于泛型接口,需要定义方法为泛型、参数泛型、还有返回值也为泛型。

interface Config{
// 定义方法泛型,参数泛型,返回值泛型
<T>(value:T):T
}

var getData:Config= function<T>(value:T):T{
return value;
}

getData<string>('list');
// OK

// getData<string>(123);
// 报错

泛型接口也可以用以下这种方式定义。

// 定义方法泛型,参数泛型,返回值泛型
interface Config<T>{
(value:T):T
}

function getData<T>(value:T):T{
return value;
}

var myData:Config<string> = getData;

myData('list');
// OK

// myData(123);
// 报错

5. 泛型类与泛型接口的实际运用;

在数据库的操作中,经常会有增、删、改、查的操作,对于这些操作可以分别封装一个泛型类,在添加不同的实体时都可以用,比如添加用户,添加文章,添加购买商品,在使用这个泛型类时只需要分别定义不同的用户类、文章类和商品类做校验就可以了。

// 操作数所库的泛型类
class MySQL<T>{
add(info:T):bollen{
// 向数据库写入数据
console.log(info);
return true;
}
}

// 给user表添加数据
// 定义一个user类,和数据库进行映射
class User{
username:string | undefined;
password:string | undefined;
}
// 实列化一个User,并添加数据。
var user = new User();
user.username = 'admin';
user.password = '123456';

var USER_DB = new MySQL<User>();
USER_DB.add(user);

当添加的字段较多时,还可以在实例化类的时候就添加数据。

// 操作数所库的泛型类
class MySQL<T>{
// 添加方法--略
add(info:T):bollen{
// 向数据库写入数据
console.log(info);
return true;
}
// 更新方法
updated(info:T,id:number):bollean{
// 更新数据库的文章表--略
console.log(info,id);
return true;
}
}

// 给article表添加数据
// 定义一个article类,和数据库进行映射
class Article{
title:string | undefined;
desc:string | undefined;
status:number |undefined;

constructor(params:{
title:string | undefined,
desc:string | undefined,
status?:number | undefined
}){
this.title = params.title;
this.desc = params.desc;
this.status = params.status
};
}
var article = new Article({
title:'哈哈哈',
desc:'搞笑故事',
status:0
});

var ARTICLE_DB = new MySQL<Article>();

// 添加数据
ARTICLE_DB.add(article);

// 更新数据
ARTICLE_DB.updated(article,10);

如果要操作多个不同种类的数据库,还可以为数据库定一个泛型类,使每个数据库都有增、删、改、查的方法。