TypeScript 1.5 now has decorators.
Could someone provide a simple example demonstrating the proper way to implement a decorator and describe what the arguments in the possible valid decorator signatures mean?
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;
Additionally, are there any best practice considerations that should be kept in mind while implementing a decorator?
You could implement something that logs each call to the console:
One important thing I don't see in the other answers:
Decorator factory
Check the TypeScript handbook Decorators chapter.
I ended up playing around with decorators and decided to document what I figured out for anyone who wants to take advantage of this before any documentation comes out. Please feel free to edit this if you see any mistakes.
General Points
Method / Formal Accessor Decorator
Implementation parameters:
target
: The prototype of the class (Object
).propertyKey
: The name of the method (string
|symbol
).descriptor
: ATypedPropertyDescriptor
— If you're unfamiliar with a descriptor's keys, I would recommend reading about it in this documentation onObject.defineProperty
(it's the third parameter).Example - Without Arguments
Use:
Implementation:
Input:
Output:
Notes:
this
will not be the instance's if you do.@enumerable(false)
and@log
at the same time (Example: Bad vs Good)TypedPropertyDescriptor
can be used to restrict what method signatures (Method Example) or accessor signatures (Accessor Example) the decorator can be put on.Example - With Arguments (Decorator Factory)
When using arguments, you must declare a function with the decorator's parameters then return a function with the signature of the example without arguments.
Static Method Decorator
Similar to a method decorator with some differences:
target
parameter is the constructor function itself and not the prototype.Class Decorator
Implementation parameter:
target
: The class the decorator is declared on (TFunction extends Function
).Example use: Using the metadata api to store information on a class.
Property Decorator
Implementation parameters:
target
: The prototype of the class (Object
).propertyKey
: The name of the property (string
|symbol
).Example use: Creating a
@serialize("serializedName")
decorator and adding the property name to a list of properties to serialize.Parameter Decorator
Implementation parameters:
target
: The prototype of the class (Function
—it seemsFunction
doesn't work anymore. You should useany
orObject
here now in order to use the decorator within any class. Or specify the class type(s) you want to restrict it to)propertyKey
: The name of the method (string
|symbol
).parameterIndex
: The index of parameter in the list of the function's parameters (number
).Simple example
Detailed Example(s)