Skip to content

Promise.catch should have a return type of <TResult>, not T. #3834

Closed
@MicahZoltu

Description

@MicahZoltu

Current implementaiton:

interface Promise<T> {
    then<TResult>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => TResult | PromiseLike<TResult>): Promise<TResult>;
    then<TResult>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => void): Promise<TResult>;

    catch(onrejected?: (reason: any) => T | PromiseLike<T>): Promise<T>;
}

What I believe is a more correct implementation:

interface Promise<T> {
    then<TResult>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => TResult | PromiseLike<TResult>): Promise<TResult>;
    then<TResult>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => void): Promise<TResult>;

    catch<TResult>(onrejected?: (reason: any) => TResult | PromiseLike<TResult>): Promise<TResult>;
    catch<TResult>(onrejected?: (reason: any) => void): Promise<TResult>;
}

I believe the spec says that catch(x) behaves the same as then(undefined, x), which implies that catch should be a generic method with a TResult type.

If I am misunderstanding the spec, enlightenment would be appreciated.

Activity

basarat

basarat commented on Jul 13, 2015

@basarat
Contributor

catch<TResult>(onrejected?: (reason: any) => void): Promise<TResult>; is wrong in that if you have a catch and it does indeed end up getting called then if onRejected returns void the following promise chain will get Promise<void> not Promise<TResult>

That said the promise definition is best effort and not designed to be 100% correct, but the change you are recommending is not one that should be done 🌹

basarat

basarat commented on Jul 13, 2015

@basarat
Contributor

On second reading your suggestion isn't bad and maybe worth doing. I just wanted to point out that it is still best effort.

danquirk

danquirk commented on Jul 13, 2015

@danquirk
Member

@rbuckton might have something to say here

MicahZoltu

MicahZoltu commented on Jul 13, 2015

@MicahZoltu
ContributorAuthor

I'm actually not entirely sure what happens if you chain a promise to a catch that doesn't return. Does the original promise result get chained through? Does the chain get stopped prematurely?

Example:

promise.catch(error => {
    // intentionally does not return, is this considered a programming error?
}).catch(error => {
    console.log(error); // what does this do?
});

I believe the answer to this question would shed some light on what the signature should look like.

basarat

basarat commented on Jul 14, 2015

@basarat
Contributor

I believe the answer to this question would shed some light on what the signature should look like.

Here is a concrete example with comments to show what will happen:

Promise.reject(new Error('I want to get caught')).catch(error => {
    // I have caught the error and swallowed it silently
}).catch(error => {
    // This never gets called as the error has been caught by the previous catch
}).then(foo=>{
   // foo is the return of the first `catch` and therefore `void`
});

I just wanted to point out that it is still best effort.

Basically a true implementation starts to feel like JAVAs throws : http://stackoverflow.com/a/29287864/390330

added
DeclinedThe issue was declined as something which matches the TypeScript vision
and removed on Jun 23, 2021
RyanCavanaugh

RyanCavanaugh commented on Jun 23, 2021

@RyanCavanaugh
Member

There doesn't seem to be much demand for this, and without sample code it's hard to evaluate what the deficit is.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    DeclinedThe issue was declined as something which matches the TypeScript visionSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @basarat@MicahZoltu@RyanCavanaugh@danquirk@mhegazy

        Issue actions

          Promise.catch should have a return type of <TResult>, not T. · Issue #3834 · microsoft/TypeScript