TypeScript学习第七篇 - 泛型

2020-11-26 14:45:08 浏览数 (1)

1. 泛型的定义

软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性, 组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能。

在像C#和Java这样的语言中,可以使用泛型来创建可重用的组件,一个组件可以支持多种类型的数据, 这样用户就可以以自己的数据类型来使用组件。

在TypeScript中,我们可以使用 any 类型来让函数返回多种类型,比如一个函数既可以返回 string 类型,也可以返回 number 类型,这样虽然实现了支持多种类型的数据,但是却放弃了类型检查,可能会导致传入的类型与返回的类型不一致。

为此,TypeScript中的泛型就是解决类、接口方法的复用性、以及对不特定数据类型的支持(类型校验)。

2. 泛型函数

代码语言:javascript复制
// T表示泛型,具体什么类型是调用这个方法的时候决定的。
function getData<T>(value:T):T{
    return value;
}
getData<number>(123456);
// OK 

// getData<number>('123456');
// 报错


// 如果返回的数据不确定类型,可以改成any类型,只对传参类型进行约束就可以了。
function getAnyData<T>(value:T):any{
    return value;
}

3. 泛型类

定义一个函数,求最小堆算法,需要同时支持返回数字与字符类型。

代码语言:javascript复制
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 num = new MinClass<number>();

num.add(1);
// OK

// num.add('2');
// 报错

4. 泛型接口

对于泛型接口,需要定义方法为泛型、参数泛型、还有返回值也为泛型。

代码语言:javascript复制
interface Config{
    // 定义方法泛型,参数泛型,返回值泛型
    <T>(value:T):T
}

var getData:Config= function<T>(value:T):T{
    return value;
}

getData<string>('list');
// OK

// getData<string>(123);
// 报错

泛型接口也可以用以下这种方式定义。

代码语言:javascript复制
// 定义方法泛型,参数泛型,返回值泛型
interface Config<T>{
    (value:T):T
}

function getData<T>(value:T):T{
    return value;
}

var myData:Config<string> = getData;

myData('list');
// OK

// myData(123);
// 报错

5. 泛型类与泛型接口的实际运用。

在数据库的操作中,经常会有增、删、改、查的操作,对于这些操作可以分别封装一个泛型类,在添加不同的实体时都可以用,比如添加用户,添加文章,添加购买商品,在使用这个泛型类时只需要分别定义不同的用户类、文章类和商品类做校验就可以了。

代码语言:javascript复制
// 操作数所库的泛型类
class MySQL<T>{
    add(info:T):bollen{
        // 向数据库写入数据
        console.log(info);
        return true;
    }
}

// 给user表添加数据
// 定义一个user类,和数据库进行映射
class User{
    username:string | undefined;
    password:string | undefined;
}
// 实列化一个User,并添加数据。
var user = new User();
user.username = 'admin';
user.password = '123456';

var USER_DB = new MySQL<User>();
USER_DB.add(user);

当添加的字段较多时,还可以在实例化类的时候就添加数据。

代码语言:javascript复制
// 操作数所库的泛型类
class MySQL<T>{
    // 添加方法--略
    add(info:T):bollen{
        // 向数据库写入数据
        console.log(info);
        return true;
    }
    // 更新方法
    updated(info:T,id:number):bollean{
        // 更新数据库的文章表--略
        console.log(info,id);
        return true;  
    }
}

// 给article表添加数据
// 定义一个article类,和数据库进行映射
class Article{
    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 article = new Article({
    title:'哈哈哈',
    desc:'搞笑故事',
    status:0
});

var ARTICLE_DB = new MySQL<Article>();

// 添加数据
ARTICLE_DB.add(article);

// 更新数据
ARTICLE_DB.updated(article,10);

如果要操作多个不同种类的数据库,还可以为数据库定一个泛型类,使每个数据库都有增、删、改、查的方法。

0 人点赞