我最终与装饰员一起玩耍,并决定将我想出的内容记录下来,以便在发布任何文档之前为希望利用此功能的人提供帮助。如果发现任何错误,请随时进行编辑。
一般要点
- 装饰器在声明类时调用,而不是在实例化对象时调用。
- 可以在同一类/属性/方法/参数上定义多个装饰器。
- 构造函数上不允许使用装饰器。
有效的装饰器应为:
- 可分配给装饰器类型(
ClassDecorator | PropertyDecorator | MethodDecorator | ParameterDecorator
)之一。
- 返回可分配给修饰值的值(对于类修饰器和方法修饰器)。
参考
方法/形式访问器装饰器
实现参数:
示例-不带参数
用:
class MyClass {
@log
myMethod(arg: string) {
return "Message -- " + arg;
}
}
实现方式:
function log(target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) {
const originalMethod = descriptor.value; // save a reference to the original method
// NOTE: Do not use arrow syntax here. Use a function expression in
// order to use the correct value of `this` in this method (see notes below)
descriptor.value = function(...args: any[]) {
// pre
console.log("The method args are: " + JSON.stringify(args));
// run and store result
const result = originalMethod.apply(this, args);
// post
console.log("The return value is: " + result);
// return the result of the original method (or modify it before returning)
return result;
};
return descriptor;
}
输入:
new MyClass().myMethod("testing");
输出:
方法参数为:[“ testing”]
返回值为:消息-测试
笔记:
示例-带参数(装饰器工厂)
使用参数时,必须声明带有装饰器参数的函数,然后返回带有示例签名且不带参数的函数。
class MyClass {
@enumerable(false)
get prop() {
return true;
}
}
function enumerable(isEnumerable: boolean) {
return (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) => {
descriptor.enumerable = isEnumerable;
return descriptor;
};
}
静态方法装饰器
与方法装饰器类似,但有一些区别:
- 它的
target
参数是构造函数本身而不是原型。
- 描述符是在构造函数而不是原型上定义的。
类装饰器
@isTestable
class MyClass {}
实现参数:
target
:装饰器的类在(TFunction extends Function
)上声明。
用法示例:使用元数据api在类上存储信息。
物业装饰
class MyClass {
@serialize
name: string;
}
实现参数:
target
:该类的原型(Object
)。
propertyKey
:属性的名称(string
| symbol
)。
用法示例:创建@serialize("serializedName")
装饰器并将属性名称添加到要序列化的属性列表中。
参数装饰器
class MyClass {
myMethod(@myDecorator myParameter: string) {}
}
实现参数:
target
:该类的原型(Function
—似乎Function
不再起作用。您现在应该在此处使用any
或Object
,以便在任何类中使用装饰器。或者指定要限制其使用的类类型)
propertyKey
:方法的名称(string
| symbol
)。
parameterIndex
:函数参数列表中的参数索引(number
)。
简单的例子
详细的例子
@Injectable
装饰器中,请参阅