Search code examples
typescripttypescript-typingsanonymous-classtypescript-decorator

Add a class property using a decorator in TypeScript


I'm trying to create a decorator that adds a property to its target class.

This is my decorator implementation:

export type Constructable<T> = new (...args: any[]) => T;

export function ValidationSchema() {
  return <BaseClass extends Constructable<{}>>(target: BaseClass) =>
    class extends target {
      constructor(...args: any[]) {
        super(...args);
      }

      validate() {
        console.log(this);
      }
    };
}

And this is how I apply the decorator:

@ValidationSchema()
export class Test {
  public foo: string;
}

This works fine but when I try to call the validate method on a class instance I get the error that the property doesn't exist on the type. Using // @ts-ignore I can get around this issue and it works as expected.

Is there a way for me to get TypeScript to recognize that a class instance of Test (or any other class that is decorated with the decorator) is actually of the type of my anonymous class returned in the decorator?

I've already had a look at a GitHub issue which was revolving around a similar problem and Mixin calsses, though I couldn't figure out how I would implement that in my decorator approach. Is this even possible using decorators or am I better off using a factory function?

Thank you so much in advance for any suggestions!


Solution

  • Sadly I don't think that's possible, in my opinion decorators are great to add "hidden" things, but if you need to explicitly access the properties/methods you're adding, I would use some other stragety, something like:

    function addThing<T>(obj: T): T & { thing: () => ... } {
      // code
    }