Home > other >  Is it possible to use a return value of the function in decorator function?
Is it possible to use a return value of the function in decorator function?

Time:12-18

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"

Playground

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);
  • Related