In a typescript project, there are about 2000+ events(methods) that are fired when user triggers an operation and when that operation get finished. So, for all the events that are triggered when an operation gets finished, I want to have some kind of performance metrics, so a parameter 'executionTime' should be mandatory. I am planning to add method decorator above all those events for which execution time must be present as a parameter. Below is my code
class AllEvents {
@performanceDecorator()
public static firstEvent(param1: string, param2: string, executionTime: number): void {
//some tasks...
}
@performanceDecorator()
public static secondEvent(param1: string, param2: string): void {
//some tasks...
}
@performanceDecorator()
public static thirdEvent(param1: string, param2: string, executionTime: number): void {
//some tasks...
}
}
function performanceDecorator(value: boolean) {
//..................
}
I am new to typescript, and not able to figure out the code that I should write in the body of function performanceDecorator, such that if some method does not have a parameter named 'executionTime', it will throw errors.
Expanding on my earlier comment
Since the number of parameters cannot be fixed in your scenario, there will be no easy way to figure out which one of your parameter is the executionTime.
So make an options class with the expected parameters as the properties to it. Like this
class EventOptions {
public params: string[];
public executionTime?: number;
}
class AllEvents {
@performanceDecorator
public static firstEvent(eventOptions: EventOptions): void {
//some tasks...
console.log(eventOptions.params, eventOptions.executionTime);
}
@performanceDecorator
public static secondEvent(eventOptions: EventOptions): void {
//some tasks...
}
@performanceDecorator
public static thirdEvent(eventOptions: EventOptions): void {
//some tasks...
}
}
Here, I have made the executionTime
as an optional parameter to suit your usecase. But you can go ahead and make it a required field and then you wont need to have a decorator to check the validity of the field. Typescript will do it for you.
And then to move on to the decorator:
Function Decorators have three parameters to it,
target
which is the calling class, in this case AllEvents
propertyKey
which is the name of the method as a stringdescriptor
which is a property descriptor. It has all the metadata related to your functionAnd we can write your decorator as:
function performanceDecorator(
target: Object,
propertyKey: string,
descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = (...args) => {
if (!args[0].executionTime) {
throw Error("Execution Time is missing!");
}
return originalMethod.apply(this, args);
}
return descriptor;
}
Here, we first take the original method implementation out. And then use a condition to check the availability of executionTime parameter. If not present, we thorw an error. And if present we call the original method implementation.