'Typescript ClassDecorator target type

I'm writing my own decorators in typescript. Currently, my decorators look like this:

const Controller = (prefix = ''): ClassDecorator => (target: any): void => {
  // My Logic
};

export default Controller;

My question is about the ClassDecorator argument. Currently, I'm using the any type for the target parameter but I need a specific type for this argument. So my question is how is this type named?

I googled for a while but found nothing about this.



Solution 1:[1]

You shouldn't need to explicitly state the return type of Controller because the compiler will infer it. as long as you type the arguments of your inner function ..

type MyType = { foo: number }

function f() {
  console.log('f(): evaluated')
  return function (target: MyType) {
    console.log('f(): called' + target.foo)
  }
}

``

Solution 2:[2]

Another way to do it is create an interface and have your class implements it.

// interface.ts 
export interface ExampleInterface {
    // just some method that is going to get use 
    start(): void 
    stop(): void 
}

Then in your decorator

import { ExampleInterface } from 'interface'
export function ExampleDecorator(target: ExampleInterface ) {
    // do things with your decorator 
}

Now create your class

import { ExampleInterface } from 'interface'
import { ExampleDecorator } from 'decorator'

@ExampleDecorator
export class ExampleClass implements ExampleInterface {

   start(): void {
      // do your start thing
   }

   stop(): void {
      // do  your stop thing 
   }

   someOtherMethod() {
      // do some other thing
   }

   set someSetter(value: string) {
      // set some other value 
   }
}

I use this on class / method / accessor decorator, all pass the type checking.


Another way to make it more generic which is using generic

This example is from a library I created


export function Validate<T>(rules?: ValidatorRules) {
  return (target: T, propertyName: string): void => {
    // more code ... 
  }
}

The above example is a method decorator that accept a rules.

class YourApi {

    @Validate<YourApi>()
    myMethod(name: string, value: number) {
        // do your thing 
    }

}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Damian Green
Solution 2