Parameter Decorators
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:
- Either the constructor function of the class for a static member, or the prototype of the class for an instance member.
- The name of the member.
- The ordinal index of the parameter in the function’s parameter list.
NOTE A parameter decorator can only be used to observe that a parameter has been declared on a method.
The return value of the parameter decorator is ignored.
The following is an example of a parameter decorator (@required
) applied to parameter of a member of the Greeter
class:
1 2 3 4 5 6 7 8 9 10 11 12 | class Greeter { greeting: string; constructor(message: string) { this .greeting = message; } @validate greet(@required name: string) { return "Hello " + name + ", " + this .greeting; } } |
We can then define the @required
and @validate
decorators using the following function declarations:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | import "reflect-metadata" ; const requiredMetadataKey = Symbol( "required" ); function required(target: Object, propertyKey: string | symbol, parameterIndex: number) { let existingRequiredParameters: number[] = Reflect.getOwnMetadata(requiredMetadataKey, target, propertyKey) || []; existingRequiredParameters.push(parameterIndex); Reflect.defineMetadata(requiredMetadataKey, existingRequiredParameters, target, propertyKey); } function validate(target: any, propertyName: string, descriptor: TypedPropertyDescriptor<Function>) { let method = descriptor.value; descriptor.value = function () { let requiredParameters: number[] = Reflect.getOwnMetadata(requiredMetadataKey, target, propertyName); if (requiredParameters) { for (let parameterIndex of requiredParameters) { if (parameterIndex >= arguments.length || arguments[parameterIndex] === undefined) { throw new Error( "Missing required argument." ); } } } return method.apply( this , arguments); } } |
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.
NOTE This example requires the
reflect-metadata
library. See Metadata for more information about thereflect-metadata
library.
Please login to continue.