TS04 TS中的泛型、泛型类(重要)

TypeScript中的泛型

1.1 泛型的定义

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

1.2 泛型函数
/**
 * 泛型的举例
 */

//只能返回string类型的数据
function getData(value: string): string {
    return value;
}

//同时返回string类型和number
//方法1:类型定义两个函数,缺点代码冗余

function getData1(value: string): string {
    return value;
}

function getData2(value: number): number {
    return value
}


//方法2:使用any 缺点,相当于放弃了类型检测
function getData3(value: any): any {
    return value;
}


/**
 * 需求:传入什么返回什么类型(传入的参数和返回的参数一致)
 * 例如:传入number返回number  传入string返回string
 * 方法:使用泛型,可以支持不特定的数据类型
 * T表示泛型,具体是什么类型调用这个方法的时候决定的
 */

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

//   调用
console.log(getData4<number>(123));
console.log(getData4<string>('kjh'));


// 同时我们可以任意指定返回的类型参数为any等
function getData5<T>(value: T): any {
    return value;
}


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

class minClass {
    public list: number[] = [];

    add(num: number) {
        this.list.push(num);
    }

    minNumber(): 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;
    }
}

//使用minClass
var m = new minClass();
m.add(1)
m.add(2)
m.add(10)
m.add(99)

console.log(m.minNumber());
//1


/**
 * 问题来了,上面我们封装的类不能满足传入字符串返回字符串,传入数字返回数字的要求
 * 方法:使用泛型类解决问题
 */


class minClass2<T>{
    public list:T[] = [];

    add(value:T):void{
        this.list.push(value);
    }

    minNumber():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;
    }
}

//调用泛型类
//实例化类  并且制定了类的T代表的类型是number
var m1 = new minClass2<number>();
m1.add(1)
m1.add(2)
m1.add(3)
console.log(m1.minNumber()); //1


//实例化类  并且制定了类的T代表的类型是string
var m2 = new minClass2<string>();
m2.add('a')
m2.add('b')
m2.add('c')
console.log(m2.minNumber());  //a
1.4 泛型接口
/**
 * 泛型接口
 */

 
 /**
  * 先定义一个函数接口
  * 缺点:只能传入string类型
  */

 interface ConfigFn{
     (value1:string,value2:string):string;
 }

 var setData:ConfigFn = function(value1:string,value2:string):string{
     return value1 + value2;
 }

 console.log(setData('name','张三'));


 /**
  * 第一种定义泛型的方法
  * 使用泛型接口
  * 要求:按照我们传入的数据类型进行判断
  */

  interface ConfigFn2 {
    <T>(value:T):T;
  }

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

  console.log(getData<string>('张三'));
  console.log(getData<number>(999));


  /**
  * 第二种定义泛型的方法
  * 使用泛型接口
  * 要求:按照我们传入的数据类型进行判断
  */

  interface ConfigFn3<T>{
      (value:T):T;
  }

  var myGetData:ConfigFn3<string> = function<T>(value:T):T{
      return value;
  }

  console.log(myGetData('20'))
2.1 深入泛型类(超级重点)
  • 把类作为参数来约束数据传入的类型:定义一个User的类这个类的作用就是映射数据库字段
    然后定义一个MysqlDb的类这个类用于操作数据库,之后把user类作为参数传,入到MysqlDb中
/**
 * 解释:把类作为参数来约束数据传入的类型
 * 定义一个User的类这个类的作用就是映射数据库字段
 * 然后定义一个MysqlDb的类这个类用于操作数据库
 * 后把user类作为参数传,入到MysqlDb中
 */



//User类来映射数据库字段
class User{
    userName:string | undefined;
    passWord:string | undefined;
}

//定义一个MysqlDb的类这个类用于操作数据库
class MySqlDB{
    add(user:User):boolean{
        console.log(user);
        return true;
    }
}


var u = new User();
u.userName = 'admin';
u.passWord = '123456';

var Db = new MySqlDB();
Db.add(u);
//User {userName: "admin", passWord: "123456"}



/**
 * 接下来我们再定义一个文章类
 */

class Article{
    title:string | undefined;
    status:string | undefined;
    desc:string | undefined;
}

//定义一个MysqlDb的类这个类用于操作数据库
class MySqlDB2{
    add(article:Article):boolean{
        console.log(article);
        return true;
    }
}


var a = new Article();
a.title = '时间去哪儿了'
a.status = '200'
a.desc = '宝鸡新闻网'

var Db2 = new MySqlDB2();
Db2.add(a);
//Article {title: "时间去哪儿了", status: "200", desc: "宝鸡新闻网"}


  • 但是我们发现一个问题,如果数据库中有多个字段,我们需要每次重新定义mysqlDB类
/**
 * 问题:如果数据库中有多个字段,我们需要每次重新定义mysqlDB类
 * 解决:使用泛型类解决重复封装
 */

//定义操作数据库的泛型类
class MysqlDB<T>{
    add(info: T): boolean {
        console.log(info);
        return true;
    }
}


//这时候我想定义一个User类

class User {
    userName: string | undefined;
    passWord: string | undefined;
}

var u = new User();
u.userName = 'admin'
u.passWord = '123456'

//使用User类来约束泛型类
var DB = new MysqlDB<User>();



//我又想定义一个Aritcile类
class Article {
    title: string | undefined;
    status: string | undefined;
    desc: string | undefined;
}

var a = new Article();
a.title = '时间去哪儿了'
a.status = '200'
a.desc = '宝鸡新闻网'

var Db2 = new MysqlDB<Article>();



//这样我一个泛型类,可以给多个数据库字段使用
//实例化的时候进行传值
class Person{
    name:string | undefined;
    age:number|undefined;
    id:number | undefined;
    constructor(params:{
        name:string | undefined,
        age:number | undefined,
        id?:number | undefined
    }){
        this.name = params.name;
        this.age = params.age;
        this.id = params.id;
    }
}

var p = new Person({
    name:'张三',
    age:20
})

var db = new MysqlDB<Person>();


  • 数据库修改
/**
 * 修改数据库数据
 */

//定义操作数据库的泛型类
class MysqlDB<T>{
    //增加
    add(info: T): boolean {
        console.log(info);
        return true;
    }

    //修改
    updata(info:T,id:number):boolean{
        console.log(info)
        console.log(id);
        return true;
    }
}



class Person{
    name:string | undefined;
    age:number|undefined;
    id:number | undefined;
    constructor(params:{
        name:string | undefined,
        age:number | undefined,
        id?:number | undefined
    }){
        this.name = params.name;
        this.age = params.age;
        this.id = params.id;
    }
}

var p = new Person({
    name:'张三',
    age:20
})

var db = new MysqlDB<Person>();
db.updata(p,12);
//Person {name: "张三", age: 20, id: undefined}

p.id = 12;
db.updata(p,12);
// Person {name: "张三", age: 20, id: 12}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值