Skip to content

Marking a function async changes how return type annotation effects type inference #24629

@ethanresnick

Description

@ethanresnick

TypeScript Version: 3.0.0-dev.201xxxxx

Search Terms:
promise return type inference async signature

Code

type CPSFunction<T> = (cb: (err: any, res: T) => void) => void;

function promisify<T>(fn: CPSFunction<T>): Promise<T> {
  return new Promise((resolve, reject) => {
    fn((err, res) => { err  ? reject(err) : resolve(res); });
  });
}

async function promisify2<T>(fn: CPSFunction<T>): Promise<T> {
  return new Promise((resolve, reject) => {
    fn((err, res) => { err  ? reject(err) : resolve(res); });
  });
}

Expected behavior:
The compiler should treat these functions identically.

Actual behavior:
In the first case, the returned promise, which would be inferred as Promise<{}> in the absence of the return type annotation, is instead inferred as Promise<T>, and the function compiles.

The second function fails to compile, with the error: Type '{}' is not assignable to type 'T'.

Playground Link:
http://www.typescriptlang.org/play/index.html#src=type%20CPSFunction%3CT%3E%20%3D%20(cb%3A%20(err%3A%20any%2C%20res%3A%20T)%20%3D%3E%20void)%20%3D%3E%20void%3B%0D%0A%0D%0Afunction%20promisify%3CT%3E(fn%3A%20CPSFunction%3CT%3E)%3A%20Promise%3CT%3E%20%7B%0D%0A%20%20return%20new%20Promise((resolve%2C%20reject)%20%3D%3E%20%7B%0D%0A%20%20%20%20fn((err%2C%20res)%20%3D%3E%20%7B%0D%0A%20%20%20%20%20%20if(err)%20%7B%0D%0A%20%20%20%20%20%20%20%20reject(err)%3B%0D%0A%20%20%20%20%20%20%7D%20else%20%7B%0D%0A%20%20%20%20%20%20%20%20resolve(res)%3B%0D%0A%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%7D)%3B%0D%0A%20%20%7D)%3B%0D%0A%7D%0D%0A%0D%0Aasync%20function%20promisify2%3CT%3E(fn%3A%20CPSFunction%3CT%3E)%3A%20Promise%3CT%3E%20%7B%0D%0A%20%20return%20new%20Promise((resolve%2C%20reject)%20%3D%3E%20%7B%0D%0A%20%20%20%20fn((err%2C%20res)%20%3D%3E%20%7B%0D%0A%20%20%20%20%20%20if(err)%20%7B%0D%0A%20%20%20%20%20%20%20%20reject(err)%3B%0D%0A%20%20%20%20%20%20%7D%20else%20%7B%0D%0A%20%20%20%20%20%20%20%20resolve(res)%3B%0D%0A%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%7D)%3B%0D%0A%20%20%7D)%3B%0D%0A%7D

Related Issues:

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScript

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions