Skip to content

Incorrect return types for Promise#catch and 0- and 2- arg forms of Promise#then #9193

Closed

Description

@jeffreymorlan
Expression (p: Promise) Correct type Current type
p.then() Promise Promise<{}>
p.then(b => 1) Promise Promise
p.then(b => 1, e => 'error') Promise<number string>
p.then(b => 1, e => {}) Promise<number void>
p.then(b => 1, e => {throw Error()}) Promise Promise
p.then(b => 1, e => Promise.reject(Error())) Promise Promise
p.catch(e => 'error') Promise<boolean string>
p.catch(e => {}) Promise<boolean void>
p.catch(e => {throw Error()}) Promise Promise
p.catch(e => Promise.reject(Error())) Promise Promise

Using overloading and the new never type, PromiseLike/Promise could be typed to handle all these cases correctly:

interface PromiseLike<T> {
    then(): PromiseLike<T>;
    then<R1>(onfulfilled: (value: T) => R1 | PromiseLike<R1>): PromiseLike<R1>;
    then<R1, R2>(onfulfilled: (value: T) => R1 | PromiseLike<R1>,
                 onrejected: (reason: any) => R2 | PromiseLike<R2>): PromiseLike<R1 | R2>;
}

interface Promise<T> {
    then(): Promise<T>;
    then<R1>(onfulfilled: (value: T) => R1 | PromiseLike<R1>): Promise<R1>;
    then<R1, R2>(onfulfilled: (value: T) => R1 | PromiseLike<R1>,
                 onrejected: (reason: any) => R2 | PromiseLike<R2>): Promise<R1 | R2>;
    catch<R2>(onrejected: (reason: any) => R2 | PromiseLike<R2>): Promise<T | R2>;
}

declare var Promise: {
    reject(reason: any): Promise<never>; // Returned promise is never fulfilled
};

Activity

  1. mhegazy commented on Jun 15, 2016

    @mhegazy
    Contributor
  2. rbuckton commented on Jun 15, 2016

    @rbuckton
    Contributor

    There are a few things we need to fix in the checker for properly handling never in these cases with async functions, and there's a breaking change in the definition for PromiseLike and Promise that needs to be resolved, but this seems like the right direction.

  3. added a commit that references this issue on Jun 16, 2016
    fb9806b
  4. locked and limited conversation to collaborators on Jun 19, 2018
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

    FixedA PR has been merged for this issueSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions