Returning an AngularJS $q promise with TypeScript

All we need is an easy explanation of the problem, so here it is.

I have a service that wraps $http with my functions returning a deferred object.

My interface:

export interface MyServiceScope {
    get: ng.IPromise<{}>;
}

My class:

export class MyService implements MyServiceScope {

    static $inject = ['$http', '$log'];

    constructor(private $http: ng.IHttpService,
                private $log: ng.ILogService,
                private $q: ng.IQService) {
        this.$http = $http;
        this.$log = $log;
        this.$q = $q;
    }

    get(): ng.IPromise<{}> {
        var self = this;
        var deferred = this.$q.defer();

        this.$http.get('http://localhost:8000/tags').then(
            function(response) {
                deferred.resolve(response.data);
            },
            function(errors) {
                self.$log.debug(errors);
                deferred.reject(errors.data);
            }
        );

        return deferred.promise;
    }
}

The compilation is failing with the following error:

myservice.ts(10,18): error TS2420: Class 'MyService' incorrectly implements interface 'MyServiceScope'.
    Types of property 'get' are incompatible.
        Type '() => IPromise<{}>' is not assignable to type 'IPromise<{}>'.
            Property 'then' is missing in type '() => IPromise<{}>'.

For reference, here is the IPromise definition from DefinitelyTyped. The IQService.defer() call returns an IDeferred object, and then deferred.promise returns IPromise object.

I’m not sure if I’m using the wrong definitions in my interface, or not returning the deferred object the same way. Any input would be greatly appreciated!

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

In your interface you defined a property get and in the service implementation it’s a function get(). What you probably want is a function, so the interface should be:

export interface MyServiceScope {
    get(): ng.IPromise<{}>;
}

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply