Skip to content

Generic parameter inference for Promise.then oddity #11022

Closed
@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

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions