TS泛型

TS泛型

泛型可以创建可重用的组件,一个组件可以支持多种类型,解决类,接口,方法的复用性,以及对不确定数据类型的使用

class MinCla<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
    }
}
//这样做的一个好处是可以做类型校验,如果是any就不行,这是泛型的特点,传入什么类型返回什么类型是一致的
var m=new MinCla<number>()
m.add(1)
m.add(3)
console.log(m.min());//1
var m1=new MinCla<string>()
m1.add('a')
m1.add('z')
console.log(m1.min());//a

泛型接口用法跟泛型类差不多就是把类型换成泛型就行了

interface Config{
    
    
        <T>(value1:T):T
}
var getData:Config =function<T>(value1:T){
    
     //直接在后面加:泛型接口名称,注意类和接口都可以作为参数传入
    return value1
}
//第二种写法
interface Config<T>{
    
    
        (value1:T):T
}
function getData<T>(value1:T):T{
    
    
    return value1
}
var myGetData:Config<string>=getData

把类作为参数类型的泛型类

//把类作为参数约束数据传入的类型
class User {
    
    
   username:string|undefined;
   password:string|undefined
}
class MySql<T> {
    
    
    add(user:T):boolean{
    
     //把User类型作为参数赋值进去
        console.log(user);//打印出User对象
        return true
    }
}
var u=new User();
u.password='123456'
u.username="张三"
var Db=new MySql<User>();
Db.add(u)

TS命名空间(namespace)

命名空间属于内部模块,主要用于模块避免命名冲突,一个模块里可以有多个命名空间

namespace A{
    
    
	//因为命名空间是私有的,所以需要暴露出来
	export 代码
}
//调用
var a=new A.类名/方法名

TS装饰器

普通装饰器不传参

//扩展类,方法的功能
function logClass(params:any){
    
    
	console.log(params);//params作为第一个参数,默认就是Animal这个类
	//动态扩展逻辑代码
	params.prototype.run=function(){
    
    
	}
}
@logClass//注意后面不要冒号
class Animal{
    
    
	//逻辑代码
}

装饰器工厂可以传参

function logClass(params:string){
    
    
	return function(target:any){
    
    
		console.log(params);//字符串参数
        console.log(target);//target打印出来就是Animal这个类	
	}
}
@logClass('字符串参数')//注意后面不要冒号
class Animal{
    
    
	//逻辑代码
}

装饰器还可以重载类或者方法

function logClass(params:any){
    
    
   return class extends params {
    
    
      apiUrl:any='我是修改的'
      getData(){
    
    
          this.apiUrl=this.apiUrl+'---------0'
          console.log(this.apiUrl);
      }
   } 
}
@logClass
class HttpClient {
    
    
    public apiUrl:string|undefined;
    constructor() {
    
    
        this.apiUrl='我是构造函数里面的apiurl'
    }
    getData(){
    
    
        console.log(this.apiUrl);
    }
}
var http=new HttpClient();
http.getData()//我是修改的---------0

装饰器中每个参数打印的结果

//类装饰器
function logClass(params:any){
    
    
	return function(target:any){
    
    
    	 console.log(params);//12345 装饰器参数
     	 console.log(target);//target打印出来就是这个HttpClient类	
 }
}
//属性装饰器
function shuxing(params:any){
    
    
    return function(target:any,attr:any){
    
    
        console.log(params);//属性参数
        //getData跟a方法组成的数组对象,对于静态成员来说就是类的构造函数,对于实例来说就是类的原型对象 
        console.log(target);
        console.log(attr); //apiUrl  就是属性名称
        target[attr]=params//修改属性
    }
}
//方法装饰器
function logMethod(params:any){
    
    
    return function(target:any,mName:any,desc:any){
    
    
        console.log(params);//aaa 方法参数
        console.log(target);//当前类
        console.log(mName);//getdata方法名
        console.log(desc);//描述信息 desc.value就是当前方法可以用于修改方法
        //扩展属性
        target.name='张三'
        target.Fn=function(){
    
    
            console.log(111)
        }
    }
}
@logClass(12345)
class HttpClient {
    
    
    @shuxing('属性参数')
    public apiUrl:string|undefined;
    constructor() {
    
    
        // this.apiUrl='我是构造函数里面的apiurl'
    }
     @logMethod('aaa')
    getData(){
    
    
        console.log(this.apiUrl);//属性参数
    }
    a(){
    
    

    }
}
var http=new HttpClient();
http.getData()
console.log(http.name); //张三
console.log(http.Fn);//fn扩展方法

猜你喜欢

转载自blog.csdn.net/weixin_48255917/article/details/112255501