The process of wrapping a class with a decorator causes superclasses to be unable to access that classes' properties. Why?
I have some code that:
Here is the code:
function wrap(target: any) { // the new constructor var f: any = function (...args) { return new target(); } f.prototype = target.prototype; return f; } @wrap class Base { prop: number = 5; } class Extended extends Base { constructor() { super() } } var a = new Extended() console.log(new Extended().prop) // I'm expecting 5 here, but I get undefined.
I'm sure this is some nuance of either prototypes in general or the specific way that TypeScript handles them that I do not grasp.
Decorators provide a way to add both annotations and a meta-programming syntax for class declarations and members. Decorators are a stage 2 proposal for JavaScript and are available as an experimental feature of TypeScript. NOTE Decorators are an experimental feature that may change in future releases.
TypeScript decorators are cool, but still experimental and not standardised.
The first parameter is commonly called target . The sealed decorator will be used only on class declarations, so your function will receive a single parameter, the target , which will be of type Function . This will be the constructor of the class that the decorator was applied to.
It's possible to use as many decorators on the same piece of code as you desire, and they'll be applied in the order that you declare them. This defines a class and applies three decorators — two to the class itself, and one to a property of the class: @log could log all access to the class.
This is the more modern approach using the latest TS (3.2.4). The below also uses the decorator factory pattern so you can pass in attributes:
function DecoratorName(attr: any) { return function _DecoratorName<T extends {new(...args: any[]): {}}>(constr: T){ return class extends constr { constructor(...args: any[]) { super(...args) console.log('Did something after the original constructor!') console.log('Here is my attribute!', attr.attrName) } } } }
See here for more info: https://www.typescriptlang.org/docs/handbook/decorators.html#class-decorators
This code works for me:
function logClass(target: any) { // save a reference to the original constructor var original = target; // the new constructor behaviour var f : any = function (...args) { console.log("New: " + original.name); //return original.apply(this, args); return new original(...args); // according the comments } // copy prototype so intanceof operator still works f.prototype = original.prototype; // return new constructor (will override original) return f; } @logClass class Base { prop: number = 5; } class Extended extends Base { constructor() { super() } } var b = new Base() console.log(b.prop) var a = new Extended() console.log(a.prop)
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