zoukankan      html  css  js  c++  java
  • Typescript的泛型/泛型接口

    泛型

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

    泛型的定义和函数

    // 只能返回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:比如有个最小堆算法,需要同时支持返回数字和字符串两种类型,通过类的泛型来实现

    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())
    

      

    泛型接口

    // 函数类型接口
    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方法

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

    // 定义接口
    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是实现了验证的
    

      

  • 相关阅读:
    竞赛备考建议
    谷山丰的一生
    从首个IMO季军谈起 作者 : 付云皓
    孔庆东:单刀赴高考
    LaTeX 技巧 802:国内期刊 CCT 模板编译经验
    数学书籍推荐
    翻译
    printf中用法详解
    黎活明给程序员的忠告【转】
    log4j2配置文件log4j2.xml详解(转载)
  • 原文地址:https://www.cnblogs.com/double-W/p/12875623.html
Copyright © 2011-2022 走看看