Can a TypeScript decorator function detect it is being invoked as a decorator?

52 Views Asked by At

Ignoring the potential nightmare, pain, and death this might create for a moment... Is there any way for a function to detect if it is being invoked as a decorator from within the function itself?

The idea would be to export something that can be used either as a decorator or as a function on its own.

Take this simplified example:

function Foo() {
  const isInvokedAsDecorator = ???

  // do some common stuff
  
  if (isInvokedAsDecorator) {
    return target => {
      // do some decorator stuff...
    }
  } else {
    // do some non-decorator stuff...
  }
}

@Foo()
class Test {

}

Foo()
1

There are 1 best solutions below

0
Ken La On

In your case, I see two things you can do. First is just add an argument as :

function Foo(isDecorator: true): (...args: any[]) => any
function Foo(isDecorator: false): any
function Foo(isDecorator: boolean) {

  // do some common stuff
  
  if (isDecorator) {
    return target => {
      // do some decorator stuff...
    }
  } else {
    // do some non-decorator stuff...
  }
}

@Foo(true)
class Test {

}

Foo(false)

But you can change also change like this :

function Foo(constructorFunction: Function): void
function Foo(): any
function Foo(constructorFunction?: Function) {

  // do some common stuff
  
  if (constructorFunction) {
    // Do some things to the class directly on constructorFunction.prototype
  } else {
    // do some non-decorator stuff...
  }
}

@Foo // Invoke decorator without '()'
class Test {

}

Foo()