Search code examples
javascriptangulartypescriptstrong-typing

Return type of a function that returns a chained promise


I have a class that returns a chained promise, first promise's type is angular.IPromise<Foo>, the second promise resolves with type angular.IPromise<Bar>.

Why is it the return type of doSomething angular.IPromise<Bar>?

I would have thought that the return type would be angular.IPromise<Foo> since that's the first thing that is returned by the function. I am aware that then() returns a promise and will wrap what is returned by it into the response of that, but this is still confusing me.

import { Something } from '../somewhere';
import { Bar } from '../somewhereelse';

class Test {
    doSomething(): angular.IPromise<Bar> {
        return Something.getFoo() // getFoo() return type angular.IPromise<Foo>
            .then(() => {
                let x: Bar = {};        
                return x; 
            });
    }
}

Any help would be appreciated. I am more than happy to give any more code if required.


Solution

  • First thing is : you don't return Something.getFoo(). You return Something.getFoo().then(...). Even if promises are used to execute asynchronous tasks, they are returned immediately.

    then() returning a angular.IPromise the returned promise is not the one from Something.getFoo() but the one returned by Something.getFoo().then(...)

    and as the callback provided to then() is returning a Bar object: promise.ten(foo=>return new Bar()) your statement actually returns a Promise<Bar> object.

    as @TsatsuyukiIshi stated, this is the type definition of angular.IPromise.then :

    then<X>(successCallback: (promiseValue: T) => IPromise<X>|X, ...): IPromise<X>
    

    this method is generic, and its return type (X) depends on the type that is provided as parameter ((promiseValue: T) => IPromise<X>|X).

    If you replace X by Bar this is obvious:

    then(successCallback: (promiseValue: T) => IPromise<Bar>|Bar, ...): IPromise<Bar>