Typescript泛型

泛型:泛型就是解决 类 接口 方法的复用性、以及对不特定数据类型的支持

实现方法:function method<T>(value:T):T{} 这个T只是用法最多的,但不是写死的,你想用A,B什么来代替也一样

为什么说解决复用性?大家想一下,如果我们要定义一个方法,但是要约束传入的参数和返回的类型一致,也就是说,我传入参数1,要返回number类型,传入‘张三’,要返回string类型,那么现在是不是要写两个方法分别来约束,这就造成了冗余,为了解决这个问题,我们可以使用泛型来定义约束

1、泛型函数

//旧方法约束传参和返回类型保持一致
function getData(value:number):Number{
    return value
}
function getData_c(value:string):string{
    return value
}
//泛型解决传参和返回类型一致
function getData<T>(value:T):T{
    return value
}
console.log(getData<number>(123)) //<number>传入number 那么value必须为number 传入string时就会报错
console.log(getData<string>('123'))

2、泛型类

实现一个类 来找到数组中的最小值,数组元素类型不定

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

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

    min():number{
        let minNum=this.list[0]
        for(var i=0;i<this.list.length;i++){
            if(this.list[i]<minNum){
                minNum=this.list[i]
            }
        }
        return minNum
    }
}
var a=new minCount()
a.add(1)
a.add(2)
a.add(3)
alert(a.min())

这种方法弊端:辛辛苦苦写了一个类,最终只能比较数字类型,要是想比较字符串类型还要重构,这也太麻烦了,下面看改造成泛型的类

class minCount<T>{
    public list:T[]=[]

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

    min():T{   
        let minNum=this.list[0]
        for(var i=0;i<this.list.length;i++){
            if(this.list[i]<minNum){
                minNum=this.list[i]
            }
        }
        return minNum
    }
}
var a=new minCount<number>()
a.add(1)
a.add(2)
a.add(3)
// a.add('1') //错误 不能赋值给number类型
var b=new minCount<string>()
b.add('a')
b.add('b')
b.add('c')
看下泛型都是用在哪些地方

1、类的后边
2、数组类型
3、add方法的传参
4、min方法的返回值

这四处既能够很好的保证你传入的参数和返回参数一致,又能降低冗余,起到了限制的作用和不确定数据类型的约束

3、泛型接口

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

var getYear:config=function<T>(value:T):T{
    return value
}
var c=getYear<string>('张三')  //正确
// var c=getYear<number>('张三')  //错误

4、类作为参数约束传入数据的类型

这个举例子来说可能更明了一些:假设你想定义一个方法,这个方法是往数据库传入数据的,但是你要做一个约束,不能让非法类型的数据传入数据库。
比如定义一个用户类,要求传入用户名和密码,这时候如果传入的是性别或者其他属性,肯定是不行的。这时候就要用到类作为参数来约束传入数据的类型,可以理解为接口的特性,就是起到约束的作用。
然后你还有一个文章类,你要传入title,desc,type等属性,这时候如果传入的参数是年龄,大小这些属性肯定也是不行的,这时候你就要用到文章类来约束传入的参数。下面看具体的例子

class User{
    username:string | undefined;
    password:string | undefined;
}

class Artical{
    title:string | undefined;
    desc:string | undefined;
    type:string | undefined
}

class mysqlDB{
    //定义一个方法 传入的参数要遵从User类 
    add(value:User):boolean{
        console.log(value)
        return true
    }
}

//这样定义的类如果想要约束多个类的规范 就必须重复的写多个 这时候使用泛型 就可以避免重复了
class mysqlDB_c{
    //定义一个方法 传入的参数要遵从User类 
    add(value:Artical):boolean{
        console.log(value)
        return true
    }
}

var u=new User()
// u.username='张三'
u.password='123445'
var params={
    name:'09'
}

var DB=new mysqlDB()
var DB_C=new mysqlDB_C()
// DB.add(params)  //错误 这里的params不符合user类的规范
// DB.add(u)

var artical=new Artical()
artical.title='学习'
artical.desc='学习让人进步'

DB_C.add(artical)

这样虽然可以实现约束效果,但是如果还有更多的类约束,那么岂不是要写很多的mysqlDB类,这样显然不可行,下面看使用泛型来解决这个问题。

class User{
    username:string  | undefined;
    password:string | undefined;
}

class Artical{
    title:string | undefined;
    desc:string | undefined;
    type:string | undefined;
    constructor(params:{  //这里再次进行传入参数约束 必须穿入title,desc type 可不传
        title:string | undefined;
        desc:string | undefined;
        type?:string | undefined;  
    }){
        this.title=params.title,
        this.desc=params.desc,
        this.type=params.type
    }
}

//这样定义一个泛型类 在实例化的时候可以传入约束类 避免了重复构造mysqlDB类
class mysqlDB<T>{
    add(value:T):boolean{
        console.log(value)
        return true
    }

    update(value:T,id:number):boolean{
        console.log(value,id)
        return true
    }
}
var u=new User()
u.username='张三'

var a=new Artical({
    title:'好好学习',
    desc:'天天向上'
})

var db=new mysqlDB<User>()
db.add(u)

var db1=new mysqlDB<Artical>()
db1.add(a)
db1.update(a,12)

这里定义user类和artical类的时候有些区别,artical类直接在内部实现了constructor,这样就可以直接在实例化的时候传参,而且可以看到artical类在构造的时候也是进行了约束的,这样约束之后在传参的时候就必须传入title,desc参数,type参数是可选的

mysqlDB类在定义的时候使用了泛型的方法,<T>确保了实例化对象的时候使用了哪种类约束。使用了哪种规范就必须按照这种方式来传参了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容