4

Is there a way to do code weaving in TypeScript?

What I'm trying to do is inject a piece of code as the very first line of every function in my TypeScript app and I don't wont to do this manually (this manual approach is tedious and error prone).

Gigitsu
  • 593
  • 6
  • 19

1 Answers1

4

While not true compile-time weaving, for class methods only you can use method decorators to wrap those methods with additional functionality at runtime. Consider this example method decorator, which makes invocation also log the received arguments into the console:

// the method decorator function
function log(target: Object, key: string, descriptor: any) {
    // replace original property descriptor of method with the following one:
    return {
        // the new method:
        value: function (...args: any[]) {
            // log arguments
            console.log(args);

            // invoke the original method as part of the new method,
            // and return its returned value (if any)
            return descriptor.value.apply(this, args);
        }
    };
}

Applying this decorator to a method is as trivial as:

class Calculator {
    @log
    add(a: number, b: number) {
        return a + b;
    }
}

Quick explanation: a method decorator in Typescript has the following signature:

<T>(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor<T>) => PropertyDescriptor<T> | void;

In other terms, the method decorator takes in 3 arguments:

  1. The prototype object on which the original method is defined
  2. The property key of the method
  3. The property descriptor of the method

A method decorator returns a single property descriptor, which is a replacement for that of the original method on the type.

John Weisz
  • 30,137
  • 13
  • 89
  • 132
  • I was reading the [exact same thing](http://goo.gl/rE21Hu) :) I think that decorators are appropriate for the problem but I still need to manually decorate every single method, is there a way to avoid this? Can I "implicitly" decorate every methods? – Gigitsu Feb 11 '16 at 11:07
  • @Gigitsu You could use a [class decorator](https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Decorators.md#class-decorators) to decorate all methods of a type (by iterating over own properties of the prototype and see if they are functions), but I know no way for automatically adding method decorators to *every single method* in your entire codebase. – John Weisz Feb 11 '16 at 11:13