typescriptecmascript-nexttypescript-decoratortypescript-5

TypeScript 5 - Access class constructor from a property decorator


In TypeScript 5 the property decorator's type definition has changed and there does not seem to be a way to get a class's constructor.

It now implements the TC39 proposal where the first parameter to a property decorator is always undefined:

type ClassFieldDecorator = (value: undefined, context: {
  kind: "field";
  name: string | symbol;
  access: { get(): unknown, set(value: unknown): void };
  static: boolean;
  private: boolean;
}) => (initialValue: unknown) => unknown | void;

While previously, the first parameter to the decorator function was the class's constructor:

function myPropertyDecorator(target: Object, propertyKey: string) { 
  ...
}

An ability to get a class's constructor was very useful for some libraries, e.g. validation libraries, that were operating on a class level and were storing a map of validations per class.

What are the options for doing this with the new decorator's proposal?

  1. Get a class constructor in the initialization function?
  2. Use experimentalDecorators instead of new decorators?
  3. Something else?

Solution

  • You can have access to the class instance in the callback function of the decorator :

    function propDecorator(value: undefined, ctx: ClassFieldDecoratorContext) {
        return function (this: any, initialValue: any) {
          console.log(this, this.constructor)
          return initialValue;
        };
    }
    
    class C {
      @propDecorator x = 1;
    }
    
    new C();
    

    Make sure you don't use an arrow function to not keep the context of the decorator function.

    Playground