目录

typeScript-装饰器

typeScript 装饰器

TypeScript装饰器

要使用装饰器需要在tsconfig.json中启用experimentalDecorators选项

{
  "compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}

1、类装饰器
可以给类添加属性、方法, 或者重写类的方法
返回值(可选): 如果类装饰器有返回值,就会替换掉原来的构造方法

function classDecorator(contructor: any) {
	contructor.property.newName = "新增的属性";

	const originNormalFunc = contructor.property.normalFunc;
	contructor.property.normalFunc = function () {
		if(originNormalFunc) {
			originNormalFunc.call(this);
		}
		//todo 这里可以添加附加的逻辑
		console.log("附加逻辑");
		return constructor;
	}
}

@classDecorator
class MyClass {
    name: string;
    
    constructor(name: string) {
        this.name = name;
        console.log('MyClass 实例化');
    }
    normalFunc() {
    	consloe.log("normalFunc");
    }
}

2、方法装饰器
func(target: any, objectKey: string, decriptor: PropertyDescriptor)

target:方法所属的类的原型对象(对于静态方法是类的构造函数)
普通方法通过target.constructor.name获取类名
静态方法通过target.name获取类名

propertyKey:方法名
descriptor:方法的属性描述符(PropertyDescriptor)
descriptor是一个PropertyDescriptor对象,包含以下属性
interface PropertyDescriptor { value?: any; // 值(此处为函数本身) writable?: boolean; // 是否可写 enumerable?: boolean; // 是否可枚举 configurable?: boolean; // 是否可配置 get?(): any; // getter 函数 set?(v: any): void; // setter 函数 }

function funcDecorator (target: any, objectKey: string, descriptor: PropertyDescriptor) {
    const originFunc = descriptor.value;
    decriptor.value = function(...args: any[]) {
		const result = originFunc.aplay(this, args);
		//todo 重新逻辑
		console.log("重写逻辑");
		return result;
	}
	return decriptor;
}

class Calculator {
    @funcDecorator 
    add(a: number, b: number): number {
        return a + b;
    }
}

3、属性装饰器
propertyDecorator(garget: any, objectKey: string)

target:类的原型对象(对于静态成员是类的构造函数)
propertyKey:属性名

function TestPropoerty(target: Object, propertyKey: string) {
    console.log(`对象: ${target.constructor.name}的属性: ${propertyKey}被装饰`);
}

function LogProperty(target: Object, propertyKey: string) {
  const propDesc = Object.getOwnPropertyDescriptor(target, propertyKey);
  console.log(`属性: ${propertyKey} ${propDesc}`);
}

class User {
    @TestPropoerty
    @LogProperty
    name: string = "A";
}