是否可以在装饰器函数中使用函数的 return 值?

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

我想使用函数的输出值作为函数正在使用的装饰器的输入。例如,像这样的东西:

function dec(otherFuncOutput: string) {
  console.log(otherFuncOutput)
}

@dec
function otherFunc(): string {
  const otherFuncOutput: string = "output";
  return otherFuncOutput;
}

这样做的正确方法是什么?

Typescript 装饰器 can be applied to a class declaration, method, accessor, property, or parameter but ,所以我假设您想使用 class 方法来完成此操作。

所以这样做,您需要检查 属性 描述符,获取它描述的函数值并将其替换为调用原始函数并对其输出执行某些操作的新函数。

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

在 Alex 给出正确答案后,我还找到了如果装饰函数有输入参数如何使用它:

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