TypeScript
写下博客主要用来分享知识内容,并便于自我复习和总结。
如有错误之处,请各位大佬指出。
泛型:软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性。组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时,为我们提供了十分灵活的功能。
在像C#和Java这样的语言中,就可以使用泛型来创建可重用的组件,一个组件可以支持多种类型的数据。这样用户就可以用自己的数据类型来使用组件。
通俗理解:泛型就是解决 类 接口 方法 的复用性、以及对不特定数据类型的支持。
泛型的定义
首先先来看一下泛型的使用场景。
使用普通函数,它只能返回一个类型的数据。
function getData(value:string):string{
return value;
}
使用函数重载,代码冗余很明显。
function getInfo(name:string):string;
function getInfo(age:number):number;
function getInfo(str:any):any{
if(typeof str === "string"){
return "我是:"+str;
}else{
return "我的年龄:"+str;
}
}
直接使用any,当然可以解决问题。
function getAny(value:any):any{
return value;
}
但这么做,首先它和js就无区别了,ts的优势根本没有展现,使用any相当于放弃了类型检查。其次,这么做完全没有任何限制,就算数据传错也不会报错,
这显然不是我们想要的。那现在,我就想在传入number时返回number,同时也可以在传入string时返回string,就需要泛型。
泛型:可以支持不特定的数据类型,实现复用性。
// 这里的T表示泛型,(当然可以用其它字母,推荐T)
// 具体什么类型是调用这个方法的时候决定的
function getData<T>(value:T):T{
return value;
}
console.log(getData<number>(123));
// 泛型相比于any的优势:存在类型检查
// 报错:getData<number>('123');
那么在泛型中需要注意的就是,上面代码中的return时不能给一个具体数据类型的值,因为传进来的数据类型和返回值的数据类型不一定相同,所以会报错。
那我们想改变一下返回值的数据类型,只需要:
function getData<T>(value:T):any{
return value;
}
简例:
class MinClass<T>{
public list:T[] = [];
add(value:T):void{
this.list.push(value);
}
min():T{
let minNum = this.list[0];
for(let i = 0; i < this.list.length; i++){
if(minNum > this.list[i]){
minNum = this.list[i];
}
}
return minNum;
}
}
// 制定了T代表number
let m = new MinClass<number>();
m.add(1);
m.add(2);
console.log(m.min());
// 制定了T代表string
let s = new MinClass<string>();
s.add('a')
s.add('c')
console.log(s.min())
泛型接口
使用方法一:
interface ConfigFn{
<T>(value:T):T;
}
let getData:ConfigFn = function<T>(value:T):T{
return value;
}
console.log(getData<string>('李四'));
使用方法二:
interface ConfigFn<T>{
(value:T):T;
}
function getData<T>(value:T):T{
return value;
}
let myGetData:ConfigFn<string> = getData;
console.log(myGetData('张三'));
把类作为参数类型的泛型类
// 模拟操作数据库的泛型类
class MysqlDb<T>{
add(info:T):boolean{
console.log(info);
return true;
}
}
class User{
username: string;
password: string;
}
let u = new User();
u.username = '李四';
u.password = '123456';
// 类当作参数的泛型类
let Db = new MysqlDb<User>();
Db.add(u);
class ArtCate{
title: string;
desc: string;
constructor(params:{
title: string,
desc?: string
}) {
this.title = params.title;
this.desc = params.desc;
}
}
let a = new ArtCate({
title: '标题',
desc: '描述'
});
// 类当作参数的泛型类
let Db2 = new MysqlDb<ArtCate>();
Db2.add(a);