TypeScript中的范型

一、定义

比如我们有一个函数,如果不使用范型是这样的

function getData(arg: number): number {
    return arg;
}
复制代码

它只能传入number类型,如果我们要传入一个string类型的是编译不通过的,所以我们可以写另一个函数或者用any类型

function getData1(arg: string): string {
    return arg;
}
function getData2(arg: any): any {
    return arg;
}
复制代码

那么问题来了,如果重新写那么我们就不能做到复用了,如果用any就不能保证传进去的类型和传出来的类型统一,所以我们有了范型

function getData<T>(arg: T): T {
    return arg;
}
getData<number>(123)
getData<string>(123)
getData(false)//利用了类型推论,编译器会根据传入的参数自动地帮助我们确定T的类型
复制代码

T:表示范型,具体什么类型是调用的这个方法的时候决定的(注意:T也可以是任意其他字母) 所以范型可以支持不确定的数据类型,传入的参数和返回值的类型一致。

二、范型变量

如果我们想打印一个数组的长度

function getLength<T>(arg: T): T {
    console.log(arg.length);  // Error: T doesn't have .length
    return arg;
}
复制代码

如果这么做,编译器会报错说我们使用了arg的.length属性,但是没有地方指明arg具有这个属性。 记住,这些类型变量代表的是任意类型,所以使用这个函数的人可能传入的是个数字,而数字是没有.length属性的。
现在假设我们想操作T类型的数组而不直接是T。由于我们操作的是数组,所以.length属性是应该存在的。 我们可以像创建其它数组一样创建这个数组:

function getLength<T>(arg: T[]): T[] {
    console.log(arg.length);  // Array has a .length, so no more error
    return arg;
}
复制代码

三、范型类

泛型类使用(<>)括起泛型类型,跟在类名后面。

class Minclass<T> {
    public list: T[] = []
    add(value: T):void {
        this.list.push(value)
    }
    min():T{
        let minNum = this.list[0]
        for(let i =0; i < this.list.length; i++){
            if(minNum > this.list[i]){
                minNum = this.list[i]
            }
        }
        return minNum
    }
}
let m = new Minclass<number>()
m.add(2)
m.add(6)
m.min() //2
let s = new Minclass<string>()
s.add('m')
s.add('c')
s.min()//c
复制代码

四、范型接口

interface ConfigFn{
    <T>(value:T):T
}
let getData:ConfigFn = function<T>(value:T):T{
    return value
}
复制代码

通用范型接口:

function getData<T>(value:T):T{
    return value
}
interface ConfigFn<T>{
    (value:T):T
}
let getData:ConfigFn<string> = getData
let getData1:ConfigFn<number> = getData

复制代码

五、在泛型约束中使用类型参数

class User{
    username: string
    password: string
}
class Mysql{
    add (user:User):boolean{
        console.log(user)
        return true
    }
}
let u = new User()
u.username = '张三'
u.password = '123'
let m = new Mysql()
m.add(u)
复制代码

我们可以通过范型约束来更好的实现上面的代码

class Mysql<T>{
    add(info:T):boolean{
        console.log(Info)
        return true
    }
}
let u = new User()
u.username = '张三'
u.password = '123'
let my = new Mysql<User>()
my.add(u)
复制代码

转载于:https://juejin.im/post/5d0b7c03f265da1b8811e265

猜你喜欢

转载自blog.csdn.net/weixin_34293059/article/details/93182643