A Decorator is a special kind of declaration that can be attached to a class declaration, method, accessor, property, or parameter. Decorators use the form @expression, where expression must evaluate to a function that will be called at runtime with information about the decorated declaration.
If we want to customize how a decorator is applied to a declaration, we can write a decorator factory. A Decorator Factory is simply a function that returns the expression that will be called by the decorator at runtime.
Multiple decorators can be applied to a declaration, as in the following examples:
On a single line:
On multiple lines:
When multiple decorators apply to a single declaration, their evaluation is similar to function composition in mathematics. In this model, when composing functions f and g, the resulting composite (f ∘ g)(x) is equivalent to f(g(x)).
There is a well defined order to how decorators applied to various declarations inside of a class are applied:
1. Parameter Decorators, followed by Method, Accessor, or Property Decorators are applied for each instance member. 2. Parameter Decorators, followed by Method, Accessor, or Property Decorators are applied for each static member. 3. Parameter Decorators are applied for the constructor. 4. Class Decorators are applied for the class.
A Class Decorator is declared just before a class declaration. The class decorator is applied to the constructor of the class and can be used to observe, modify, or replace a class definition. A class decorator cannot be used in a declaration file, or in any other ambient context (such as on a declare class).
The expression for the class decorator will be called as a function at runtime, with the constructor of the decorated class as its only argument.
Next we have an example of how to override the constructor.
Method Decorators: メソッド・デコレータ
A Method Decorator is declared just before a method declaration. The decorator is applied to the Property Descriptor for the method, and can be used to observe, modify, or replace a method definition. A method decorator cannot be used in a declaration file, on an overload, or in any other ambient context (such as in a declare class).
An Accessor Decorator is declared just before an accessor declaration. The accessor decorator is applied to the Property Descriptor for the accessor and can be used to observe, modify, or replace an accessor’s definitions. An accessor decorator cannot be used in a declaration file, or in any other ambient context (such as in a declare class).
NOTE TypeScript disallows decorating both the get and set accessor for a single member. Instead, all decorators for the member must be applied to the first accessor specified in document order. This is because decorators apply to a Property Descriptor, which combines both the get and set accessor, not each declaration separately.
NOTE A Property Descriptor is not provided as an argument to a property decorator due to how property decorators are initialized in TypeScript. This is because there is currently no mechanism to describe an instance property when defining members of a prototype, and no way to observe or modify the initializer for a property. As such, a property decorator can only be used to observe that a property of a specific name has been declared for a class.
NOTE The return value is ignored if your script target is less than ES5.
We can use this information to record metadata about the property, as in the following example:
We can then define the @format decorator and getFormat functions using the following function declarations:
The @format(“Hello, %s”) decorator here is a decorator factory. When @format(“Hello, %s”) is called, it adds a metadata entry for the property using the Reflect.metadata function from the reflect-metadata library. When getFormat is called, it reads the metadata value for the format.
A Parameter Decorator is declared just before a parameter declaration. The parameter decorator is applied to the function for a class constructor or method declaration. A parameter decorator cannot be used in a declaration file, an overload, or in any other ambient context (such as in a declare class).
The expression for the parameter decorator will be called as a function at runtime, with the following three arguments:
1. Either the constructor function of the class for a static member, or the prototype of the class for an instance member. 2. The name of the member. 3. The ordinal index of the parameter in the function’s parameter list.
The @required decorator adds a metadata entry that marks the parameter as required. The @validate decorator then wraps the existing greet method in a function that validates the arguments before invoking the original method.
TypeScript includes experimental support for emitting certain types of metadata for declarations that have decorators. To enable this experimental support, you must set the emitDecoratorMetadata compiler option either on the command line or in your tsconfig.json: