Search code examples
typescripttypescript-decorator

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


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?


Solution

  • 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