Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

typescript class decorator: typing properties defined in decorator function

bar is a simple class decorator that adds a property to the class Foo.

function bar(target) {
    target.inDecorator = 'in decorator';
}

@bar
class Foo {
    inClass:string;
    inDecorator:string;
    constructor() {
        this.inClass = 'a string';
    }

    getInClass() {
        return this.inClass;
    }
}

console.log(Foo.inDecorator);
console.log(Foo.prototype.inDecorator);
const foo = new Foo();
console.log(foo.getInClass());
console.log(foo.inDecorator);

The only console log that causes an error is the first, Foo.inDecorator, the inclusion of which in ts 1.5.3 gives

Property 'inDecorator' does not exist on type 'typeof Foo'.

As far as I can tell inDecorator should be defined on the prototype of Class Foo and should be available on Foo as if it were a static prop. Running the resulting js file reveals undefined for the prototype access as well as on the new foo object, however Foo.inDecorator prints correctly even though it is the source of the error. To be more clear, we get

in decorator
undefined
a string
undefined

Any ideas on how to correctly type/add a static prop or method?

Thanks!

Edited this as I originally overlooked the fact that prototype access, Foo.prototype.inDecorator was not working.

like image 655
low_ghost Avatar asked Aug 01 '15 03:08

low_ghost


People also ask

What are the property decorators in TypeScript?

A Decorator is a special kind of declaration that can be attached to a class declaration, method, accessor, property, or parameter. Decorators use the form @expression , where expression must evaluate to a function that will be called at runtime with information about the decorated declaration.

How do you write TypeScript decorators?

In TypeScript, you can create decorators using the special syntax @expression , where expression is a function that will be called automatically during runtime with details about the target of the decorator. The target of a decorator depends on where you add them.

Is decorator a type variable in TypeScript?

A Decorator is a special kind of declaration that can be applied to classes, methods, accessor, property, or parameter.

Are decorators still experimental in TypeScript?

Decorators provide a way to annotate or modify a class or class member in TypeScript. However, Decorators are still an experimental feature of the language.


1 Answers

Within the decorator target refers to the function—Foo—rather than the prototype—Foo.prototype.

So in the decorator doing target.inDecorator = ... is the same as Foo.inDecorator = ... and not Foo.prototype.inDecorator = ....

Here's one way of doing it:

interface BarStatic {
    new(): BarInstance;
    inDecorator: string;
}

interface BarInstance {
    inDecorator: string;
}

function bar(target: BarStatic) {
    target.inDecorator = 'static';
    // note that prototype will be `any` here though
    target.prototype.inDecorator = 'instance';
}

@bar
class Foo {
    static inDecorator: string; // required
    inDecorator: string;        // required
    inClass: string;

    constructor() {
        this.inClass = 'a string';
    }

    getInClass() {
        return this.inClass;
    }
}

console.log(Foo.inDecorator);           // static
console.log(Foo.prototype.inDecorator); // instance
const foo = new Foo();
console.log(foo.getInClass());          // a string
console.log(foo.inDecorator);           // instance
like image 119
David Sherret Avatar answered Oct 10 '22 22:10

David Sherret