Typescript的泛型/泛型接口

目录

回到顶部

泛型

  软件工程中,我们不仅要创建一致的定义良好的 API,同时要考虑可重用性,组件不仅能够支撑当前的数据类型,同时也能支持未来的数据类型,这在创建大型项目时为你提供了十分灵活的功能, 像 C# 和 java 语言中,可以使用范型创建可重用的组件,一个组件可以支持多种类型的数据,这样的用户就可以自己的数据类型来使用组件。通俗来说:泛型就是解决类、接口、方法的复用性、以及不特定数据类型的支持。

泛型的定义和函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// 只能返回string类型的数据
function getData(value:string):string {
    return value
}
 
// 同时能返回string类型和number类型, 当要返回string类型时使用getData(冗余)
function getData1(value:number):number {
    return value
}
 
// ts的其他的方式,实现放回string、number类型
function getData3(value:any):any {
    return value   // 但是有一个问题就是,无法实现类型检查和约束,你也不知道传入和返回是否时一致的
}
 
// 我们必须要实现一个方法传入什么类型,必须返回什么类型,这就可以使用范型了
function getData4<T>(value:T):T{  // 这里的T就是泛型,这里的T不一定时T,也可以是时A、B、C
    return value 
}
 
// 使用泛型
alert(getData4<number>(123)) // 约束传入和返回的类型为number
getData4<string>('1111'// 约束传入和返回的类型为string
 
 
function getData5<T>(value:T):any{  // 这里的T就是泛型,返回值为any
    return value 
}
 
getData5<string>('1111')

  

demo:比如有个最小堆算法,需要同时支持返回数字和字符串两种类型,通过类的泛型来实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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(2);
m.add(12);
m.add(33);
m.add(52);
alert(m.min())
 
// 上面的代码是可以传入数值返回最小值,那如果我想传入a-z的字符,能否返回其中最小的
class MinClass1<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 MinClass1<string>();  // 这里的泛型是string,当然也可以是number
m1.add('a');
m1.add('A')
m1.add('b')
alert(m1.min())

  

回到顶部

泛型接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// 函数类型接口
interface ConfigFn {
    (value1:string,value2:string):string  // 函数接口
}
 
var setData:ConfigFn = function(value1:string, value2:string):string{
    return value1+value2
}
alert(setData('name','wangwu'))  // 韩式类型接口实现
 
// 第一种定义方式:泛型接口
interface ConfigFns {
    <T>(value1:T):T;  // 泛型接口
}
 
var getData:ConfigFns = function<T>(value1:T):T{
    return value1
}
 
getData<string>("OK")
 
// 第二种定义方式
interface ConfigFnplus<T> {
    (value1:T):T;  // 泛型接口
}
 
function getData1<T>(value1:T):T{
    return value1
}
 
var myGetData:ConfigFnplus<string> = getData1
myGetData("OK,wo")

  

 泛型小 demo:

  功能: 定义一个操作数据库的库,支持 Mysql、 Mssql、Mongdb, 要求 Mysql、Mssql、Mongdb 功能一样,都有 add、update、delete、get 方法

注意:约束统一规范,以及代码的重用,解决方案:需要约束规范所以要定义接口,接口是一种规范定义,它定义了行为和动作的规范;泛型通俗理解:泛型就是解决类、接口方法的复用性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
// 定义接口
interface DBI<T>{
    add(info:T):boolean;
    update(info:T,id:number):boolean;
    delete(id:number):boolean;
    get(id:number):any[];
}   
 
 
// 实现mongdb类
class MongDb<T> implements DBI<T> {
    add(info: any): boolean {
        console.log(info)
        return true
    }
    update(info: any, id: number): boolean {
        throw new Error("Method not implemented.");
    }
    delete(id: number): boolean {
        throw new Error("Method not implemented.");
    }
    get(id: number): any[] {
        throw new Error("Method not implemented.");
    }
     
}
 
// 定义一个操作mysql数据库的类,注意:要实现泛型接口,这个类应该是一个泛型类
class MysqlDb<T> implements DBI<T>{
 
    constructor(){
        console.log('数据库实现连接')
    }
    add(info: T): boolean {
        console.log(info)
        return true
    }
    update(info: T, id: number): boolean {
        throw new Error("Method not implemented.");
    }
    delete(id: number): boolean {
        throw new Error("Method not implemented.");
    }
    get(id: number): any[] {
        throw new Error("Method not implemented.");
    }
 
 
// 操作用户表, 定义一个user类和数据表做映射
class User{
    username:string|undefined;
    password:string|undefined;
}
 
var u = new User();
u.username='张三';
u.password='123'
 
//var oMysql = new MysqlDb();  // 类作为参数约束数据传入的类型
var oMysql = new MysqlDb<User>();  // 通过指定类型去校验参数
 
oMysql.add(u); // 这里的u是实现了验证的