typescript7-decorator and mixin

decorator

  1. Need to enable "experimentalDecorators" in tsconfig.json: true
  2. Execute sequentially from top to bottom
function setName(){
    
    
    console.log('get name')
    return (target:any)=>{
    
    
        console.log('set name')
    }
}
function setAge(){
    
    
    console.log('get age')
    return (target:any)=>{
    
    
        console.log('set age')
    }
}
@setName()
@setAge()
class A{
    
    }

// get name
// get age
// set age
// set name

class decorator

let sign;
function setName(name:string){
    
    
    // target就是实例化后的对象
    return (target:new ()=>any)=>{
    
    
        sign=target;
        console.log(target.name)
    }
}
@setName("jack")
class A{
    
    }

console.log(sign===A)
// true
console.log(sign===A.prototype.constructor)
// true

function addName(constructor:new ()=>any){
    
    
    constructor.prototype.name='jack'
}
@addName
class B{
    
    }
interface B{
    
    
    name:string
}
const b=new B();
console.log(b.name)
// jack

decorator function

function classDecorator<T extends new(...args:any[])=>{
    
    }>(target:T){
    
    
    return class extends target {
    
    
        public newProperty='new property';
        public hello='override'
    }
}
@classDecorator
class Greeter {
    
    
    public Property='property';
    public hello:string
    constructor(text:string) {
    
    
        this.hello=text
    }
}

console.log(new Greeter('world'))

enum decorator

function enumerable(bool:boolean){
    
    
    return (target:any,propertyName:string,descriptor:PropertyDescriptor)=>{
    
    
        console.log(target)
        descriptor.enumerable=bool
    }
}
class A{
    
    
    constructor(public age:number) {
    
    
    }
    @enumerable(true)
    // 通过传入的值,控制是否可枚举
    getAge(){
    
    
        return this.age;
    }
}
const a=new A(18)
for (const key in a) {
    
    
    console.log(key)
    // age getAge
}
  • property decorator
function enumerable(target:any,propertyName:string){
    
    
    console.log(propertyName)
}
class A{
    
    
    @enumerable
    public age:number
    constructor(age:number) {
    
    
        this.age=age
    }
}
const a=new A(18)
  • parameter decorator
function required(target:any,properName:string,index:number){
    
    
    console.log(`修饰的是${
      
      properName}的第${
      
      index+1}个参数`)
}
class A{
    
    
    public name:string='jack';
    public age:number=20;
    public getInfo(prefix:string,@required infoType:string):any{
    
    
        return prefix+" "+this[infoType]
    }
}
interface A{
    
    
    [k:string]:string|number|((prefix:string,infoType:string) => void)
}
const a=new A();
a.getInfo('haha','age')
// 修饰的是getInfo的第2个参数

contamination

  • Mix the properties and methods of class A and class B, and the returned new class has all the properties of class A and class B
class ClassA{
    
    
    public isA!:boolean
    public funcA(){
    
    }
}
class ClassB{
    
    
    public isB!:boolean;
    public funcB(){
    
    }
}
class ClassAB implements ClassA,ClassB{
    
    
    public isA:boolean=false;
    public isB:boolean=false;
    public funcA!:()=>void;
    public funcB!:()=>void;
}
function mixins(base:any,from:any[]){
    
    
    from.forEach((fromItem)=>{
    
    
        Object.getOwnPropertyNames(fromItem.prototype).forEach(key=>{
    
    
            // 遍历属性KEY值
            base.prototype[key]=fromItem.prototype[key]
        })
    })
}
mixins(ClassAB,[ClassA,ClassB])
const ab=new ClassAB()
console.log(ab)

Guess you like

Origin blog.csdn.net/weixin_64925940/article/details/126823666