TypeScript 1.5现在有装饰器。
有人可以提供一个简单的示例来演示实现装饰器的正确方法并描述可能的有效装饰器签名中的参数的含义吗?
declare type ClassDecorator = <TFunction extends Function>(target: TFunction) => TFunction | void; declare type PropertyDecorator = (target: Object, propertyKey: string | symbol) => void; declare type MethodDecorator = <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void; declare type ParameterDecorator = (target: Function, propertyKey: string | symbol, parameterIndex: number) => void;
此外,在实现装饰器时是否应牢记任何最佳实践注意事项?
我最终玩弄了装饰器,并决定在任何文档出来之前为任何想要利用它的人记录我的发现。如果您发现任何错误,请随时编辑。
一个有效的装饰器应该是: 可分配给装饰器类型之一 ( ClassDecorator | PropertyDecorator | MethodDecorator | ParameterDecorator)。 返回一个可分配给装饰值的值(在类装饰器和方法装饰器的情况下)。 参考
一个有效的装饰器应该是:
ClassDecorator | PropertyDecorator | MethodDecorator | ParameterDecorator
参考
实现参数:
target
Object
propertyKey
string
symbol
descriptor
TypedPropertyDescriptor
Object.defineProperty
利用:
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");
输出:
方法参数是:[“测试”] 返回值为:Message – testing
方法参数是:[“测试”]
返回值为:Message – testing
笔记:
this
@enumerable(false)
@log
使用参数时,您必须声明一个带有装饰器参数的函数,然后返回一个带有示例签名的函数,不带参数。
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; }; }
类似于方法装饰器,但有一些区别:
@isTestable class MyClass {}
target``TFunction extends Function
使用示例:使用元数据 api 来存储有关类的信息。
class MyClass { @serialize name: string; }
使用示例:创建@serialize("serializedName")装饰器并将属性名称添加到要序列化的属性列表中。
@serialize("serializedName")
class MyClass { myMethod(@myDecorator myParameter: string) {} }
Function
any
parameterIndex
number
简单的例子