TypeScript--泛型

Posted intelwisd

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TypeScript--泛型相关的知识,希望对你有一定的参考价值。

3.6 泛型:

解决,类,接口,方法的复用性,以及对不特定数据类型的支持

3.6.1 泛型函数:

如果需要一个函数传入类型必须返回类型,同时满足,泛型可以解决。any类型放弃了类型检查。

function getData(value:any):any{
  return ‘hahaha‘; // 修改了返回值
}

泛型:可以支持不特定的数据类型,要求传入的参数和返回的参数一致

// T表示泛型,具体什么类型时调用这个方法的时候决定的
function getData<T>(value:T):T{
  return value;
}
getData<number>(123); //调用的时候尖括弧种写什么类型,传参些什么类型
getData<string>(123); // 报错

// 函数的返回值可以实any
function getData<T>(value:T):any{
  return ‘123123‘;
}
getData<number>(123); // √
getData<string>(‘123‘);// √

3.6.2 泛型类:

eg:有一个最小堆算法,需要同时支持返回数字和字符串两种类型

class MinClass{
  public list:number[] = [];
  add(num:number) {
    this.list.push(num);
  }
  min():number{
    var minNum = this.list[0];
    for(let i = 0;i < this.length;i++) {
      if(minNum>this.list[i]) {
        minNum = this.list[i];
      }
    }
   return minNum;
  }
}
let m = new MinClass();
m.add(23);
m.add(1);
m.add(0);
m.add(45);

m.min();// 0

泛型类:

class MinClass<T>{
  public list:T[] = [];
  add(num:T):void {
    this.list.push(num);
  }
  min():T{
    var minNum = this.list[0];
    for(let i = 0;i < this.length;i++) {
      if(minNum>this.list[i]) {
        minNum = this.list[i];
      }
    }
   return minNum;
  }
}
var m = new MinClass<number>();// ()表示实例化类,并且制定了类的T代表的类型式number
m.add(1);
m.add(3);
m.add(8); 
m.min();
// 1.可以传入任意类型
// 2.可以类型校验
var m1 = new MinClass<string>();// ()表示实例化类,并且制定了类的T代表的类型式number
m1.add(‘a‘);
m1.add(‘d‘);
m1.add(‘g‘); 
m1.min();

3.6.3 泛型接口:

// 定义一个函数接口
interface Config{
  (value1:string,value2:string):string;
}

let setData:Config=function(value1:string,value2:string) {
	return value1+value2;
}

setData(‘name‘,‘zhangsan‘);

// 改造接口泛型
// 方法1
interface Config{
  <T>(value:T):T;
}

let setData:Config=function(value:T):T {
	return value;
}

setData<string>(‘name‘);
setData<number>(123);
// 方法2
interface Config<T>{
  (value:T):T;
}
function getData<T>(value:T):T{
  return value;
}
var myGetData:config<string> = getData;
myGetData(‘123‘); // √

3.6.4 深入泛型类:

eg:定义一个user的类,主要共功能映射数据可字段然后定义一个MysqlDb的类这个类用于操作数据库然后把User类作为参数传入到MysqlDb中

class User{
  username:string | undefined;
  password:string | undefined;
}
class mysqlDb{
  add(user:User):boolean { // 通过User类检查add方法传入的参数
    console.log(user); // {username:‘seafwg‘,passwrd:‘123456‘}
    return true;
  }
}
let u = new User();
u.username = ‘seafwg‘;
u.password = ‘123456‘;

let Db = new MysqlDb();
Db.add(u);

// 改造:
class User{ // User类不变
  usenrame:string | undefined;
  password:string | undefined;
}
class MysqlDb<T>{
  add(info:T):boolean{
    console.log(info);
    return true;
  }
}
var u = new User();
u.username = ‘seafwg‘;
u.password = ‘123456‘;
var Db = new MysqlDb<User>(); // 把User类传入进行类型检查
Db.add(u);
// 增加一个articleCate类和数据库进行映射
class ArticleCate{
  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;
  }
}

let a = new ArticleCate({
	title:‘中国‘,
  desc: ‘国内新闻‘,
  status: 1
});
// 把ArticleCate类当作参数的泛型接口
let Db = new MysqlDb<ArticleCate>();
Db.add(a);

// User?{username: "seafwg", password: "123456"}
// ArticleCate?{title: "中国", desc: "国内新闻", status: 1}

3.6.5 运用:

eg:定义一个操作数据库的库,支持Mysql,MsSql,MongoDb

要求:Mysql,MsSql,MongDb功能一样,都有add,update,delete,get方法

注意:约束统一的规范,以及代码重用

解决方案:要约束规范所以要定义接口,需要代码重用所以要用到泛型

1.接口:在面向对象的编程中,接口是一种规范的定义,它定义了行为和动作的规范

2.泛型:就是解决类,接口,方法的复用性

// 定义接口
interface DBInter<T>{
  add(info:T):boolean; // 增加的时候不知道是什么类型,用泛型去检查,返回是否成功
  update(info:T,id:number):boolean;
  delete(id:number):boolean;
  get(id:number):any[];
}
// 定义一个操作mysql数据库的类
// 【注意:】要实现泛型接口,这个类也是一个泛型
// MysqlDb数据库的实现:
class MysqlDb1<T> implements DBInter<T> {
  add(info: T): boolean {
    console.log(‘MysqlDb1 info‘, info)
    return true;
    // throw new Error("Method not implemented.");
  }
  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.");
  }
}
class User1{
  username:string | undefined;
  password:string | undefined;
}
let us = new User1();
us.password = ‘123123‘;
us.username = ‘seafwg‘;

// 用户信息存储到MysqlDb1中
let oMysql = new MysqlDb1<User1>();
oMysql.add(us); // {password: "123123", username: "seafwg"}

// MsSql数据库的实现
class MsSql<T> implements DBInter<T> {
  add(info: T): boolean {
    console.log(‘MsSql info‘, 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.");
  }
}
// 用户信息存储到MsSql中
let oMssql = new MsSql<User1>();
oMssql.add(us);

以上是关于TypeScript--泛型的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 Typescript 泛型中使用 '&'

TypeScript 入门14.泛型

TypeScript专题之泛型

TypeScript 中泛型的不安全隐式转换

TypeScript——泛型

Typescript 别名泛型接口