Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript decorators does not recognize the new properties

Let's say I have a class decorator that adds some method to a class.

function decorator(target) {
  target.prototype.method = function() {};
}


@decorator
class Test {
  constructor() {
    this.method()  <------- Property method does not exists on type Test
  }
}

If I have the ability to add decorators but typescript does not recognize them, it's worth nothing.

There is a way to solve this problem?

like image 293
undefined Avatar asked Mar 19 '26 01:03

undefined


1 Answers

Decorators are used for all kinds of reasons, from modifying a class, to aspect-oriented programming, to simple logging. Almost anything can happen inside a decorator. At this time, the contents of the decorator is not used to modify the type information for the class (in some cases, it may not ever be possible to do so, although in your case it would be possible as it is such a straightforward one).

If you want to add methods to a class, you might consider TypeScript mixins as an alternative, or simple inheritance (see below).

Placeholder Implementation

A simple fix for your issue would be to provide an empty method to generate the type information you want:

@decorator
class Test {
  constructor() {
      this.method();
    }

    method(): void { }
}

Replace Constructor

An alternate solution would be to replace the constructor within the decorator - so you add the method, and the constructor call to the method, within the decorator - thus ensuring that the implementation will be there.

function decorator(target: any) {
    const original = target;

    const constr: any = (...args) => {
        const c: any = () => {
            return original.apply(null, args);
        }

        c.prototype = original.prototype;
        c.prototype.method = function () { alert('method');};

        const inst = new c();
        inst.method();
        return inst;
    }

    constr.prototype = original.prototype;

    return constr;

}

@decorator
class Test {
    constructor() {
    }
}

const test = new Test();

Inheritance

This is the boring, but often correct solution (and if you don't want to inherit, you could delegate instead):

class HasMethod {
    method() {
        alert('Method');
    }
}

class Test extends HasMethod {
    constructor() {
        super();
        this.method();
    }
}

const test = new Test();
like image 149
Fenton Avatar answered Mar 20 '26 16:03

Fenton



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!