TypeScript class decorator that modifies object instance

感情迁移 提交于 2019-12-09 05:39:48

问题


I'm making a plugin for Aurelia and need a class decorator that

  1. adds attributes to the new object instance, and
  2. calls an external function with the new object as an argument.

I've looked through examples, and so far I've put together ("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'm not entirely clear on the details here (or what is actually needed), and
  • it might not work properly since I'm getting Aurelia errors when using objects instantiated from classes with this decorator (and I suspect it's my decorator rather than the Aurelia framework that's buggy).

Any help and explanation would be greatly appreciated!


回答1:


Why not just assign those properties to the prototype, and subsequently assign to the instance on first invocation

// 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:


Here's a working version:

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;
}

(code in playground)



来源:https://stackoverflow.com/questions/41397947/typescript-class-decorator-that-modifies-object-instance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!