'How to implement a parameter decorator in TypeScript?
I've been trying to use a parameter decorator @logParameter
:
class Person {
public name: string;
public surname: string;
constructor(name : string, surname : string) {
this.name = name;
this.surname = surname;
}
public saySomethingAsync(something: string, @logParameter cb: (said : string) => void) {
cb(this.name + " " + this.surname + " says: " + something);
}
}
My problem is that when I try to implement the decorator. All the changes that I do to the target are ignored.
I've been reading some documentation and the parameter decorators are not able to modify the target.
A parameter decorator function is a function that accepts three arguments: The function that contains the decorated parameter, the property key of the member (or undefined for a parameter of the constructor), and the ordinal index of the parameter. The return value of this decorator is ignored.
The documentation says that I can annotate use the parameter decorator to
annotate the target and index
and then use a method decorator to read the annotation. It would be something like something like:
@readParameterAnnotations
public saySomethingAsync(something: string, @logParameter cb: (said : string) => void) {
cb(this.name + " " + this.surname + " says: " + something);
}
My problem is that I don't understand how can I add an annotation to the target if all changes to the target are ignored?
function logParameter(target: any, key: string, index: number) {
// how can I annotate the target?
}
Is using reflect-metadata the only way?
function logParameter(target: any, key: string, index: number) {
Reflect.defineMetadata("log_parameters", index, target, key);
}
Solution 1:[1]
The return value of this decorator is ignored.
This is irrelevant to your situation. The return value of parameter decorators is ignored because they don't need to be able to replace anything (unlike method and class decorators which can replace the descriptor).
My problem is that when I try to implement the decorator. All the changes that I do to the target are ignored.
The target is the object's prototype. It works fine:
class MyClass {
myMethod(@logParam myParameter: string) {}
}
function logParam(target: any, methodKey: string, parameterIndex: number) {
target.test = methodKey;
// and parameterIndex says which parameter
}
console.log(MyClass.prototype["test"]); // myMethod
var c = new MyClass();
console.log(c["test"]); // myMethod
Just change that situation to put the data where you want it (using Reflect.defineMetadata
is probably best).
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |