我们想要组件不仅能支持现有数据类型,也要支持未来数据类型,这时泛型
就提供了十分灵活的功能。
通俗的讲,泛型
就是解决类、接口、函数的复用性,以及对不待定数据类型的支持。
# 创建泛型
一般用一对尖括号表示泛型如 < >
,中间一般用大写 T
,形如 <T>
。
当然你可以用任何大写字母表示泛型,如<A>、<B> 。。。
,但一般习惯用<T>
。
注意:定义泛型之后,具体什么类型实在调用时决定的;
# 简单示例
场景:要求传入什么类型,返回什么类型
function test<T>(value:T):T{
return value;
}
这里并没有指定参数类型和返回类型,调用函数如下
console.log( test<number>(123) ); // 正确 指定传入的时number类型,返回也是如此
console.log( test<number>('123') ); // 错误 指定了 number 类型,但传入了字符串
test<number> : 意思是指定了number 类型
test<string> : 意思是指定了string 类型
即 具体类型在调用时指定
# 泛型接口
interface ConfigFn{
<T>(value:T):T;
}
var test:ConfigFn = function<T>(value:T):T{
return value;
}
console.log( test<string>('张三') ); // 张三
console.log( test<string>(123) ); // 错误 指定 string 类型但传入了 number
或者是如下形式
interface ConfigFn<T>{
(value:T):T;
}
function test<T>(value:T):T{
return value;
}
let t:ConfigFn<number> = test;
console.log( t(123) ); // 123
console.log( t('123') ); // 错误 指定 numbre 但传入了 string
# 泛型类
class MinClass<t>{
list:T[] = [];
add(value:T):void{
list.push(value);
}
// 堆算法:求传入值中最小值
min():T{
let m = this.list[0];
for(let i=0; i<list.length;i++){
if(m > list[i]){
m = list[i]
}
return m;
}
}
}
// 实例化类并指定了类的 T 代表的数据类型为 number
let m1 = new MinClass<number>();
m1.add(2);
m1.add(4);
m1.add(1);
m1.add('5'); //错误 指定类型为 number 但传入了 string 类型
console.log(m1.min()); // 1
// 实例化类并指定了类的 T 代表的数据类型为 string
let m2 = new MinClass<number>();
m2.add(2);//错误 指定类型为 string 但传入了 number 类型
m2.add('4');
m2.add('8');
m2.add('5');
console.log(m2.min()); // '4'
# 泛型类扩展
场景:模拟向数据添加信息
// 此种定义:在实例化时不需要传入数据
class User{
userName: string | undefined;
password: string | undefined;
}
// 此种定义:在实例化时必须传入数据
class Department{
depName: string;
depNo: number;
depStatus: number;
constructor(params:{
depName: string,
depNo: number,
depStatus: number
}){
this.depName = params.depName;
this.depNo = params.depNo;
this.depStatus= params.depStatus;
}
}
// 模拟操作数据库
class MysqlDb<T>{
add(info:T):boolean{
return true;
}
}
添加用户
let u = new User();
u.userName = '张三';
u.password = '123456';
// 实例化草操作数据库的类并指定类型为 User 类
let myDB = new MysqlDb<User>();
myDB.add(u);
添加部门
let d = new Department({
depName: '研发部',
depNo: 6688,
depStatus: 1
})
// 实例化草操作数据库的类并指定类型为 Department 类
let myDB = new MysqlDb<Department>();
myDB.add(d);
# 泛型类与泛型接口
interface Print<T>{
printFn(value:T):T;
}
// 注意 类实现泛型接口时,也必须是泛型类
class MyPrint<T> implements Print<T>{
printFn((value:T):T{
return value;
}
}
let pi = new MyPrint<number>();
console.log(pi.printFn(123)); // 123
console.log(pi.printFn('123')); // 错误
网友评论