【愚公系列】2021年12月 Typescript-泛型

2022-12-01 09:18:58 浏览数 (1)

文章目录

  • 一、typeScript中的泛型
    • 1、泛型的定义
    • 2、泛型函数
    • 3. 泛型类
    • 4. 函数定义
    • 5 泛型接口
      • 5.1 函数类型接口
      • 5.2 泛型接口(1)
      • 5.3 泛型接口(2)
      • 5.4 泛型在类中的运用
  • 二、TypeScript泛型类 把类作为参数类型的泛型类

一、typeScript中的泛型

  1. 泛型的定义
  2. 泛型函数
  3. 泛型类
  4. 泛型接口

1、泛型的定义

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

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

通俗理解:泛型就是解决 类 接口 方法的复用性、以及对不特定数据类型的支持(类型校验)

2、泛型函数

只能返回string类型的数据

代码语言:javascript复制
function getData(value:string):string{
        return value;
    }

需要同时返回 string类型 和number类型(代码冗余)

代码语言:javascript复制
function getData1(value:string):string{
     return value;
}
function getData2(value:number):number{
    return value;
}

同时返回 string类型 和number类型 ,any可以解决这个问题

代码语言:javascript复制
function getData(value:any):any{
    return value 'hello';
}
getData(123);
getData('str');

any放弃了类型检查,传入的参数类型和返回的参数类型可以不一致

代码语言:javascript复制
//any存在问题,传入值的类型,但无法获取返回值 的类型
function getData<T>(value:T):any{
    return '2145214214';
}

getData<number>(123);  //参数必须是number
getData<string>('这是一个泛型');

如果需要传入什么 返回什么。比如:传入number 类型必须返回number类型 传入 string类型必须返回string类型

泛型: 是指在定义函数/接口/类时,不预先指定具体的类型,而在使用的时候再指定类型的一种特性; 可以支持不特定的数据类型 要求:传入的参数和返回的参数一致

T表示泛型,具体什么类型是调用这个方法的时候决定的

代码语言:javascript复制
 //T 泛型变量  表示任何类型
function getData<T>(value:T):T{
    return value;
}
getData<number>(123);
getData<string>('1214231');
getData<number>('2112');       /*错误的写法*/  
代码语言:javascript复制
// 是指在定义函数/接口/类时,不预先指定具体的类型,而在使用的时候再指定类型的一种特性;
 //T 泛型变量  表示任何类型
function fun3<T>(name:T):T{    
    console.log('hello '   name);
    return name;     
};
fun3<string>('abc'); 
//定义了泛型函数后,使用方式传入参数
// 定义多个类型
fun3<string | number>('abc');    

3. 泛型类

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

代码语言:javascript复制
//下面这个只能支持数字类型
class MinClass{
    public list:number[]=[];
    add(num:number){
        this.list.push(num)
    }
    min():number{
        // var minNum = Math.min(...this.list)
        //因为要比较数字 和 字符串,所以用下面的方法

        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(30);
m.add(22);
m.add(6);
alert(m.min());

如何同时只是数字和 字符串的参数比较大小呢 ?

利用类的泛型

代码语言:javascript复制
class MinClas<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;
  }
}

//实例化类 并且制定了类的T代表的类型是number
var m1=new MinClas<number>();   
m1.add(11);
m1.add(3);
m1.add(2);
alert(m1.min())

// 实例化类 并且制定了类的T代表的类型是string
var m2 = new MinClas<string>();
m2.add("b");
m2.add("k");
m2.add("v");
alert(m2.min());

4. 函数定义

代码语言:javascript复制
//函数声明
function fun5<T>(name:T):T{    
    return name
}
//函数表达式
let fun6 = function<A>(name:A):A{
    return name;
}
//ES6
 let fun7 =<U>(name:U):U => name;

5 泛型接口

5.1 函数类型接口

代码语言:javascript复制
interface ConfigFn{
    (value1:string,value2:string):string;
}
var setData:ConfigFn=function(value1:string,value2:string):string{
    return value1 value2;
}
setData('name','张三');

如果希望能同时支持返回string,number类型接口, 上面的函数接口就达不到要求

5.2 泛型接口(1)

在接口里定义泛型

代码语言:javascript复制
interface ConfigFn{
    <T>(value:T):T;
}
var getData:ConfigFn=function<T>(value:T):T{
    return value;
}
getData<string>('张三');
// getData<string>(1243);  //错误

5.3 泛型接口(2)

代码语言:javascript复制
interface ConfigFn<T> {
  (value: T): T;
}
function getData<T>(value: T): T {
  return value;
}
var myGetData: ConfigFn<string> = getData;
myGetData("20"); /*正确*/

// myGetData(20)  //错误
代码语言:javascript复制
 //接口
interface Search{    
    <T>(a:T,b:T):boolean;
}
// 接口Search代表 有2个参数,类型为任意类型, 而且参数类型是保持一致的, 接口返回的是boolean值
// 下面是使用接口:
let f4:Search = function<T>(str1:T,str2:T):boolean{    //void无返回值
    return str1==str2;     //true/false
}
f4<number>(123,456)

5.4 泛型在类中的运用

代码语言:javascript复制
class A2<T>{
   n:T;      //表示属性的类型
   constructor(num:T){    //值的类型
       this.n = num;
   }
   action(x:T):T{
       return x
   }
};
var a2 = new A2<string>('abc');    //实例化 
a2.action('3')

二、TypeScript泛型类 把类作为参数类型的泛型类

把类作为参数来约束数据传入的类型

代码语言:javascript复制
class User{
        username:string | undefined;
        pasword:string | undefined;
        constructor(username:string,pasword:string) {
            this.username = username;
            this.pasword = pasword;
        }
    }
    
    class MysqlDb{
        allUser:any[] = [];
        add(user:User):boolean{
            console.log(user);
            this.allUser.push(user)
            return true;
        }
        getUsers(){
            console.log(this.allUser)
        }
    }
    var u1=new User('张三','123456');
    var u2=new User('李四','123456');
    var Db=new MysqlDb();
    Db.add(u1);
    Db.add(u2);
    Db.getUsers();

数组泛型

代码语言:javascript复制
//数组泛型 也可以使用数组泛型 Array<elemType> 来表示数组
let arr: Array<any> = [1, '1', true, 3, 5];   //number[]

定义返回值的类型T

我们在函数名后添加了 ,其中 T 用来指代任意输入的类型, 在后面的输入 value: T 和输出 Array 中即可使用了。

代码语言:javascript复制
 function createArray2<T>(length: number, value: T): Array<T> {
    let result: T[] = [];
    for (let i = 0; i < length; i  ) {
        result[i] = value;
    }
    return result;
}
createArray2<string>(3, 'x');

0 人点赞