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.
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.
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.
A Decorator is a special kind of declaration that can be applied to classes, methods, accessor, property, or parameter.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With