Search code examples
typescriptgeneratoriterable

What AsyncGenerator TypeScript type yields a Promise?


I'm trying to assign a return type to the function below:

async function *sleepyNumbers() {  // what TypeScript type is this?
  let n = 0;
  while (true) {
    yield new Promise(resolve => resolve(n++));
    await new Promise(resolve => setTimeout(resolve, 500));
  }
}

(async () => {
  for await (const i of sleepyNumbers())
    console.log(i);
})();

The generator is yielding a Promise that resolves to a number. Setting the type to Promise<number> fails with this error message:

TS2739: Type 'AsyncGenerator' is missing the following properties from type 'Promise': then, catch, [Symbol.toStringTag], finally

Iterable resulted in a similar error.

I can set the type to AsyncGenerator but that's not specific enough. What is the proper TypeScript syntax for the return type of this function?


Solution

  • It will be AsyncGenerator<number, never, void>:

    number - next result
    never returns
    void - next doesn't get any parameter

    You'll also need to explicitly type a promise resolve:

    yield new Promise<number>(resolve => resolve(n++));

    All together:

    async function *sleepyNumbers(): AsyncGenerator<number, never, void> {
        let n = 0;
        while (true) {
            yield new Promise<number>(resolve => resolve(n++));
            await new Promise(resolve => setTimeout(resolve, 500));
        }
    }
    
    (async () => {
        for await (const i of sleepyNumbers())
            console.log(i);
    })();