typescript中的泛型
- 泛型的定义:
软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性。组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能。
在像C#和Java这样的语言中,可以使用泛型来创建可重用的组件,一个组件可以支持多种类型的数据。这样用户就可以以自己的数据类型来使用组件。
通俗理解:泛型就是解决 类 接口 方法的复用性、以及对不特定数据类型的支持(类型校验)
//只能返回string类型的数据
//function getData(value:string):string{
// return value;
//}
//同时返回string和number类型 (代码冗余)
//function getData1(value:string):string{
// return value;
//}
//function getData2(value:string):string{
// return value;
//}
//同时返回string和number类型 any可以解决这个问题
//function getData(value:any):any{
// return value;
//}
//any放弃了类型的检查,传入什么,返回什么。比如:传入number类型必须返回number类型
//function getData(value:any):any{ //传入的参数和返回的类型可以不一致
// return "aaa";
//}
- 泛型函数:
可以支持不特定的数据类型,要求:传入的参数和返回的类型一致
//T表示泛型,具体什么类型是调用这个方法的时候决定的
function getData<T>(value:T):T{
return value;
}
//getData<number>("123")//错误写法。报错
getData<string>("123")
getData<number>(123)
- 泛型类:
比如有个最小的堆算法,需要同时返回数字和字符串的两种类型。通过类的泛型来实现
//普通类
class MinClass{
public list:number[]=[];
add(num:number){
this.list.push(num);
}
min():number{
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 m = new MinClass();
m.add(3);
m.add(22);
m.add(2);
console.log(m.min()); //2
//类的泛型:
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 m1 = new MinClass<number>(); //实例化类,并且指定了T代表的类型number
m1.add(3);
m1.add(23);
m1.add(2);
console.log(m1.min()); //2
var m2 = new MinClass<string>(); //实例化类,并且指定了T代表的类型是string
m2.add("a");
m2.add("b");
m2.add("c");
console.log(m2.min()); //a
范类:泛型可以帮助我们避免重复的代码以及对不特定数据类型的支持(类型校验)
a. 定义个类
//操作数据库的泛型类
class mysqlDb<T>{
add(info:T):boolean{
console.log(info);
return true;
}
}
//想给user表增加数据
//定义一个user类和数据库进行映射
class User{
username:string | undefined;
pasword:string | undefined;
}
var u = new User();
u.username = "张三";
u.pasword = "123456";
var Db = new mysqlDb<User>();
Db.add(u);//{username:"张三",pasword:"123456"}
class mysqlDb<T>{
//添加数据
add(info:T):boolean{
console.log(info);
return true;
}
//修改数据
updated(info:T,id:number):boolean{
console.log(info);
console.log(id);
return true;
}
}
class ArticleCate{
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 a = new ArticalCate({
// title:"分类",
// desc:"11111",
// status:1
//})
//var Db = new mysqlDb<AricleCate>();
//Db.add(a); //{title:"分类",desc:"11111",status:1}
var b = new ArticalCate({
title:"分类",
desc:"11111",
});
b.status=0;
var Db = new mysqlDb<AricleCate>();
Db.updated(a,12);//{title:"分类",desc:"11111",status:0} 12
b. 把类作为参数来约束数据传入的类型
class User{
username:string | undefined;
pasword:string | undefined;
}
class MysqlDb{
add(user:User):boolean{
console.log(user);
return true;
}
}
var u = new User();
u.username="aaa";
u.pasword="123456";
var Db = new MysqlDb();
Db.add(u);
class ArticleCate{
title:string | undefined;
desc:string | undefined;
status:number | undefined;
}
class MysqlDb{
add(user:ArticleCate):boolean{
console.log(user);
return true;
}
}
var u = new User();
u.title="国内";
u.desc="国内新闻";
u.status=1;
var Db = new MysqlDb();
Db.add(u);//{title:"国内",desc:"国内新闻",status:1}
- 泛型接口:
//定义接口(函数类型接口)
interface ConfigFn{
(value1:string,value2:string):string;
}
//实现接口
var setData:ConfigFn=function(value1:string,value2:string):string{
return value1+value2;
}
setData("name","张三")
//泛型接口1:
interface ConfigFn{
<T>(value:T):T;
}
var getData:ConfigFn = function<T>(value:T){
return value;
}
getData<string>("张三")
//泛型接口2:
interface ConfigFn<T>{
(value:T):T;
}
function getData2<T>(value:T){
return value;
}
var myGetData:ConfigFn<string> = getData2;
myGetData("张三")