Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inferred promise return type is invalid when catch is not using a arrow function #19282

Closed
ch1ll0ut1 opened this issue Oct 18, 2017 · 4 comments
Labels
Duplicate An existing issue was already created

Comments

@ch1ll0ut1
Copy link

ch1ll0ut1 commented Oct 18, 2017

TypeScript Version: 2.5.3

Code

function errorHandler(error: Error) {
  throw error;
}

function test1 () // => : Promise<string>
{
  return Promise.resolve('')
}

function test2 () // => : Promise<string>
{
  return Promise.resolve('')
    .catch((error: Error) => {
      throw error;
    });
}

function test3 () // => : Promise<string | void>
{
  return Promise.resolve('')
    .catch(errorHandler);
}
// Note: test3 as a class method has the same behavior

Expected behavior:
Functions test1 and test2 behave as exspected

Actual behavior:
The function test3 however has the return type Promise<string | void> which is not correct as functionally it has the same behavior as test2. It would never return void. As such it is a bug.

Also strange is: If i set the return type of the error handler to be of type Error. It doesnt trigger an ts error (it never returns anything). And the inferred return type of test3 is then Promise<string | Error>. The promise will never return a Error.

@ch1ll0ut1 ch1ll0ut1 changed the title Inferred promise return type invalid when function has a catch Inferred promise return type is invalid when catch uses not a anonymous inline function Oct 18, 2017
@ch1ll0ut1 ch1ll0ut1 changed the title Inferred promise return type is invalid when catch uses not a anonymous inline function Inferred promise return type is invalid when catch is not using a anonymous inline function Oct 18, 2017
@ch1ll0ut1 ch1ll0ut1 changed the title Inferred promise return type is invalid when catch is not using a anonymous inline function Inferred promise return type is invalid when catch is not using a arrow inline function Oct 18, 2017
@ch1ll0ut1 ch1ll0ut1 changed the title Inferred promise return type is invalid when catch is not using a arrow inline function Inferred promise return type is invalid when catch is not using a arrow function Oct 18, 2017
@aluanhaddad
Copy link
Contributor

aluanhaddad commented Oct 18, 2017

Here is a minimal repro:

const f = () => {
  throw Error();
}; // () => never
function g() {
  throw Error();
} // () => void

I do not believe this is specifically related to the declarations for Promises or even callback use.

Also strange is: If i set the return type of the error handler to be of type Error. It doesnt trigger an ts error (it never returns anything). And the inferred return type of test3 is then Promise<string | Error>. The promise will never return a Error.

That is correct behavior as a function that always throws is assignable to a function that returns a value of any arbitrary type. It is not related to the use of Error as a type annotation. If you over specify types you will get strange results.
For example, in your sample code you have

.catch((error: Error) => {
   throw error;
})

which is an incorrect annotation. It passes the typechecker because reason is any, making it assignable in both directions. There is no reason to assume that reason can be treated as an Error at runtime.

@ahejlsberg
Copy link
Member

Duplicate of #16608.

@ahejlsberg ahejlsberg added the Duplicate An existing issue was already created label Oct 18, 2017
@ch1ll0ut1
Copy link
Author

I see the underlying problem referenced in the duplicate issue. The issue i stated here however is not about the root cause its about having to deal with promises that have additional return type because of the error handler which creates a lot of work handling the void return in every Promise.then case. I dont care about the referenced root problem. The problem here is about Promises being not usable as they should if you use normal functions. Which limits you to use arrow functions for Promise.catch. And this for me is a bug.

@mhegazy
Copy link
Contributor

mhegazy commented Nov 6, 2017

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

@mhegazy mhegazy closed this as completed Nov 6, 2017
@microsoft microsoft locked and limited conversation to collaborators Jun 14, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants