Skip to content

AsyncGenerator doesn't play nicely with TNext = Promise<...> #44808

Closed
@magiblot

Description

@magiblot

Bug Report

🔎 Search Terms

AsyncGenerator Promise TNext

🕗 Version & Regression Information

Can reproduce in Version 4.4.0-dev (5cea46c).

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about "async", "generator" and "promise".

⏯ Playground Link

Playground link with relevant code

💻 Code

type Result = {message: string}

async function *saverGen(): AsyncGenerator<void, void, Promise<Result> | undefined> {
    let pending: Promise<Result>[] = [];
    while (true) {
        const p = yield;
        if (p != null)
            pending.push(p);
        else {
            const results = await Promise.all(pending);
            pending = [];
            console.log('Storing...');
            await storeResults(results);
        }
    }
}

function storeResults(results: Result[]) {
    console.log(results);
    return Promise.resolve();
}

🙁 Actual behavior

tsc fails to compile the code above because of the Promise<Result> | undefined type of the generator's next()'s parameter.

../../home/magiblot/tvision/tv3/bug.ts:3:29 - error TS2322: Type 'AsyncGenerator<void, void, Result>' is not assignable to type 'AsyncGenerator<void, void, Promise<Result>>'.
  Types of property 'next' are incompatible.
    Type '(...args: [] | [Result]) => Promise<IteratorResult<void, void>>' is not assignable to type '(...args: [] | [Promise<Result>]) => Promise<IteratorResult<void, void>>'.
      Types of parameters 'args' and 'args' are incompatible.
        Type '[] | [Promise<Result>]' is not assignable to type '[] | [Result]'.
          Type '[Promise<Result>]' is not assignable to type '[] | [Result]'.
            Type '[Promise<Result>]' is not assignable to type '[Result]'.
              Property 'message' is missing in type 'Promise<Result>' but required in type 'Result'.

3 async function *saverGen(): AsyncGenerator<void, void, Promise<Result> | undefined> {
                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  ../../home/magiblot/tvision/tv3/bug.ts:1:16
    1 type Result = {message: string}
                     ~~~~~~~
    'message' is declared here.

Found 1 error.

🙂 Expected behavior

Replacing Result with any in the generator signature (AsyncGenerator<void, void, Promise<any> | undefined>) makes the error go away. The program then runs as expected, which suggests that the code is valid and the problem lies in the type checking.

The program in the playground link should print the following output:

Storing...
[ { result: "1" }, { result: "2" }, { result: "3" } ]

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScriptFix AvailableA PR has been opened for this issueRescheduledThis issue was previously scheduled to an earlier milestone

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions