Search code examples
javascriptangularjstypescriptdecoratorrestangular

angular + restangular + typescript decorators error


I'm using:

  • angular 1.4
  • restangular for models
  • typescript as the language

This is my code:

  function plain(){
    return (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) => {
      var originalMethod = descriptor.value; // save a reference to the original method
      descriptor.value = function(...args: any[]) {
        var result = originalMethod.apply(this, args);
        return result.then(function stripRestangularAttributes(response){
          return response.plain();
        });
      };
      return descriptor;
    };
  }

  export class XYZ {
    @plain
    public getSomethingBySomething(data: Data): restangular.IPromise<any> {
      if (!entityKey && !period) {
        return null;
      }
      return this.restangularElement.all("route1/route2").post(data);
    }
  }

I get following error:

error TS1241: Unable to resolve signature of method decorator when called as an expression. Supplied parameters do not match any signature of call target.

It is thrown on the @plain line.

Some info:

  • Restangular methods, .post(data) in this example, return promises

I want to:

  • use a typescript method decorator to chain a single element in the promise chain. The chain element is a thenable - something that will call .plain() on restangular results, so that I would just use @plain on any method and all results will get plain()-ed automagically.
  • in other words, when restangular returns a promise (as it always does), I want to chain following to each method that has @plain decorator attached: .then(function stripRestangularAttributes(response){ return response.plain(); })

Unfortunately, I can't get what is typescript complaining about in above example.

PS I've been reading this fantastic answer as my TS decorators guide.


Solution

  • Your method decorator shouldn't return a function, according to the spec:

    declare type MethodDecorator = <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void;
    

    Try this instead:

    function plain(target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) {
        var originalMethod = descriptor.value; // save a reference to the original method
        descriptor.value = function(...args: any[]) {
            var result = originalMethod.apply(this, args);
            return result.then(function stripRestangularAttributes(response){
                return response.plain();
            });
        };
        return descriptor;
    };