TypeScript class decorator that modifies an instance of an object

I am making a plugin for Aurelia and need a class decorator which

  • adds attributes to an instance of a new object and
  • calls an external function with a new object as an argument.

I looked through the examples, and so far I have compiled ("pseudo-ish" code)

return function addAndCall(target: any): any {
    var original = target;

    var newConstructor = function (...args) {
        original.apply(this, args);
        this.newAttribute = "object instance value";
        ExternalModule.externalFunction(this);
    };

    newConstructor.prototype = Object.create(original.prototype);
    newConstructor.prototype.constructor = original;

    return <any>newConstructor;
}

but

  • I don’t quite understand the details here (or what really is needed), and
  • it may not work properly, as I get Aurelia errors when using objects created from classes with this decorator (and I suspect that this is my decorator, not the Aurelia framework).

Any help and explanation would be greatly appreciated!

+4
source share
2

// decorator
function addAndCall(cb: Function, newField: string) {
  // cb is now available in the decorator
  return function(ctor: Function): void {

    Object.defineProperty(ctor.prototype, newField, {
      value: function(...args: any[]) {
        return Object.defineProperty(this, newField, {

          value: function(...args: any[]) {
            console.log(newField, ...args);
          }

        })[newField](...args);
      }
    });
    cb(ctor);
  }
}

let callMe = (decoratedCtor) => console.log(decoratedCtor);
@addAndCall(callMe, 'propertyName')
class AddToMe {}

let addToMe = new AddToMe();
(<any>addToMe).propertyName(1, 2);
+2

:

function addAndCall(target: any) {
    var original = target;

    function construct(constructor, args) {
        var c: any = function () {
            this.newAttribute = "object instance value";
            ExternalModule.externalFunction(this);
            return constructor.apply(this, args);;
        }

        c.prototype = constructor.prototype;
        return new c();
    }

    var f: any = function (...args) {
        return construct(original, args);
    }

    f.prototype = original.prototype;
    return f;
}

( )

+1

Source: https://habr.com/ru/post/1665333/


All Articles