typescript中的泛型

  1. 泛型的定义:
    软件工程中,我们不仅要创建一致的定义良好的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";
	//}
  1. 泛型函数:
    可以支持不特定的数据类型,要求:传入的参数和返回的类型一致
//T表示泛型,具体什么类型是调用这个方法的时候决定的
	function getData<T>(value:T):T{
		return value;
	}
	//getData<number>("123")//错误写法。报错
	getData<string>("123")
	getData<number>(123)
  1. 泛型类:
    比如有个最小的堆算法,需要同时返回数字和字符串的两种类型。通过类的泛型来实现
//普通类
	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}
  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("张三")