A replacement method is a function returned by a method decorator and used instead of the class’s original method. A replacement can discard the original behavior, but it is usually more useful to call the original method and add behavior around it. section 14.2 section 14.2.1
Time a method call
In src/methodDecorator.ts, a time decorator receives the original method and a ClassMethodDecoratorContext. Its returned function records a start time, calls method.call(this, ...args), logs the duration, and returns the result. Calling the original with this and the received arguments preserves the context and inputs needed by the class method. String(ctx.name) supplies a printable name, including when the method name is a symbol. section 14.2.1
Listing 14.13 Using decorator context in the methodDecorator.ts file in the src folder
export function time(method: any, ctx: ClassMethodDecoratorContext) {
const methodName = String(ctx.name);
return function(this: any, ...args: any[]) {
const start = performance.now();
console.log(`${methodName} started`);
const result = method.call(this, ...args);
const duration = (performance.now() - start).toFixed(2);
console.log(`${methodName} ended ${duration} ms`);
return result;
}
}
The complete time decorator shows the outer decorator function and the inner replacement method. section 14.2.1
Two constraints matter when replacing methods:
- The replacement must be a suitable substitute. A decorator returning a string-producing function cannot decorate a method declared to return a number; TypeScript reports a return-type error. section 14.2
- With multiple decorators, replacement methods are built from the decorator nearest the method outward. At call time, the outer replacement can invoke the inner one, so their effects compose. section 14.5
A replacement can also retain data across calls. For example, timing replacements update a shared Map with call counts and elapsed time; an exported writeTimes function reports the accumulated results. section 14.7
