Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript class decorator that modifies object instance

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!

like image 944
jwx Avatar asked Dec 30 '16 14:12

jwx


People also ask

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. To learn more about Decorators in TypeScript, visit the Decorators proposal page.

What are class decorators in TypeScript?

The TypeScript website describes it as: “A Decorator is a special kind of declaration that can be attached to a class declaration, method, accessor, property, or parameter.” I would describe it as “a special declaration to add extra features on an existing class declaration, method, accessor, property, or parameter.”

What can decorators be applied to TypeScript?

The decorator is applied to the Property Descriptor for the method, and can be used to observe, modify, or replace a method definition. A method decorator cannot be used in a declaration file, on an overload, or in any other ambient context (such as in a declare class).

How do I create a custom decorator in TypeScript?

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.


1 Answers

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);
like image 127
William Addington Avatar answered Sep 18 '22 15:09

William Addington