Skip to content

Generic parameter inference for Promise.then oddity #11022

@rkirov

Description

@rkirov

TypeScript Version: 1.8.0 / nightly (2.0.5-dev.20160919)

Code

interface Thenable<T> {
  then<U>(then: (value: T) => U | Thenable<U>): Thenable<U>;
}

declare let x: Thenable<string>;
declare function f(): Thenable<string|null>|null;
declare function g(): Thenable<string>;

let y = x.then((_) => {
  if (Math.random() < 0.5) {
    return f();
  } else {
    return g();
  }
});

Expected behavior:
U should be inferred to be string | null as that solves the type constraints. It can be verified by explicitly adding then<string | null>.(...) which type checks.

Actual behavior:
TS errors with Argument of type '(_: string) => Thenable<string> | null' is not assignable to parameter of type '(value: string) => string | Thenable<string>'.

Oddities:
The following changes make the error disappear, while I expect them to have no relevance to the type of the closure:

  • moving line 5 to line 8 - declare let x below declare function f and g.
  • change of the type of x to Thenable<number>.
  • add a field of type T to Thenable - a: T, that would make Thenable strictly covariant.
  • replace with ternary expression - (_) => (Math.random() < 0.5) ? f() : g()

Metadata

Metadata

Assignees

Labels

Breaking ChangeWould introduce errors in existing codeBugA bug in TypeScriptFixedA PR has been merged for this issue

Type

No type
No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions