I am creating dynamic functions in typescript. On these dynamic functions, I want to add decorators. What is the best way to achieve this scenario? Is this a possibility?
Eg - Want to achieve something like this
@decorator1
@decorator2
var dynamicFunction = new Function('a', 'b', 'return a + b');
alert(dynamicFunction(2, 3));
Also, if I am creating multiple dynamic functions, how do I add decorators on them?
eg.
var dynamicFunction:Array<Functions>;
for (i=0; i<10; i++){
@decorator1
@decorator2
dynamicFunction[i] = new Function('a','b','return a+b');
}
You can't add decorators to straight functions. From the Typescript documentation (https://www.typescriptlang.org/docs/handbook/decorators.html):
Decorators
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.
When you try, you see that it does not work that way, because the decorator function written by the script assumes there is a class linked to what is being decorated, as noted on the documentation.
However, and I DO NOT RECOMMEND THIS, you could have the functions you need inside a class, then the following would apply:
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).
The expression for the method 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 Property Descriptor for the member.
You can then do some ugly hack as this typescript Playground example
I am providing the code here too, for convenience. A good thing to do if you check the typescript Playground or if you compile this code is to see the generated Javascript which shows clearly that this was not written for straight functions.
function noisy() {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
alert(`I am decorating ${ propertyKey }`);
};
}
class Test {
@noisy()
public testMethod() {
}
}
class DynamicTest {
}
const testInstance = new Test();
testInstance.testMethod();
let dynamics = ["do", "something"];
for (let dynFunction of dynamics) {
DynamicTest.prototype[dynFunction] = new Function(`alert("I am Dynamic ${dynFunction}")`);
let decorator = noisy();
decorator(DynamicTest.prototype, dynFunction, null);
}
const dynamicTestInstance = new DynamicTest();
dynamicTestInstance["do"]();
dynamicTestInstance["something"]();
function noisy() {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
alert(`I am decorating ${ propertyKey }`);
};
}
class Test {
@noisy()
public testMethod() {
}
}
class DynamicTest {
}
const testInstance = new Test();
testInstance.testMethod();
let dynamics = ["do", "something"];
for (let dynFunction of dynamics) {
DynamicTest.prototype[dynFunction] = new Function(`alert("I am Dynamic ${dynFunction}")`);
let decorator = noisy();
decorator(DynamicTest.prototype, dynFunction, null);
}
const dynamicTestInstance = new DynamicTest();
dynamicTestInstance["do"]();
dynamicTestInstance["something"]();
Without knowing your specific problem I can't think of a need for generating functions in this manner. Maybe an external logic data stream, like a rules engine? At any rate, dynamic generation of this sort is hard to test and maintain, so have that in mind and consider other approaches if possible.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With