I would like to use output value of a function as an input of decorator that the function is using. For example, something like that:
function dec(otherFuncOutput: string) {
console.log(otherFuncOutput)
}
@dec
function otherFunc(): string {
const otherFuncOutput: string = "output";
return otherFuncOutput;
}
What is the right way to do so?
CodePudding user response:
Typescript decorators can be applied to a class declaration, method, accessor, property, or parameter but not plain functions, so I'm going to assume you want to do this with a class method.
So do do this, you need to examine the property descriptor, take the function value it describes and replace it with a new function that calls the original function and does something with it's output.
function dec(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
// Check of the decorated property is a function
if (typeof descriptor.value === 'function') {
// The function that we are going to wrap
const declaredFn = descriptor.value
// Provide a new function for this property that wraps the original function
descriptor.value = () => {
// Call the method with `this` set the object with the method,
// in case that matters.
const result = declaredFn.apply(target)
// Do the thing you want with the result
console.log(result)
// Return the result from the origin function
return result
}
}
}
class A {
@dec
otherFunc(): string {
const otherFuncOutput = 'output'
return otherFuncOutput
}
}
new A().otherFunc() // logs "output"
CodePudding user response:
After the right given answer by Alex I also found how to use it if decorated function has input arguments:
function logger(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const original = descriptor.value;
if (typeof original == 'function') {
descriptor.value = function(...args) {
var result = original.apply(this, args);
console.log(result);
return result;
}
}
return descriptor;
}
class C {
@logger
add(x: number, y:number ): number {
return x y;
}
}
const c = new C();
c.add(1, 2);