microsoft/TypeScript

Async for loop falling back to Iterable<T_Sync> even if object implements AsyncIterable<T_Async>.

Closed this issue ยท 1 comments

๐Ÿ”Ž Search Terms

  • AsyncIterable
  • for await

๐Ÿ•— Version & Regression Information

  • This changed between versions N/A and N/A
  • This changed in commit or PR N/A
  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about _________
  • I was unable to test this on prior versions because _______

โฏ Playground Link

https://www.typescriptlang.org/play/?target=99#code/PTAEBcE8AcFNQMrgE6wIYFsA8AVAggDSg4BCAfKALygDeAUCKE0wNoKQYBGA9gDYB0AS3CxkacN2QBdABQBKAFygAkiLGdesVaPGTceMgG4GYZqDYceAtAGdIAOwDG2sROnyleO05doNWtV1kXHJjRgBfOjooOEQUdGwcAH12JyJkrwdHCmpff1wUrIoAMlBMn0D8jO9sqMdeWxsy2nDjesbQEhbjOlss0AAzAFcncEFue1Bebm5oGRt4zCUkVEwsQk6yOVo6M0ZuAGslADc0ZEE-TVAAAzRr0EEm7gGIGHhrvGvd5gHJUBlHBMFqA0KBnqAFqsMNsaJFvkxGCQ0AATE5nC7+G6ce42AAW3CGvGRoE48HBMXeJGu6QQIJsNlEImJHy+Zl+yBBAHc0MJ-oD7MDOGCXpCEjDIpEgA

๐Ÿ’ป Code

type Stream<T_Sync, T_Async> = Iterable<T_Sync> & AsyncIterable<T_Async>

class A {};
class B {};

async function loop(stream: Stream<A, B>) {
    // ok: variable `a` is of type `A`
    for (const a of stream) {}

    // Bad: variable `b` should be of type `B`, TS asserted `A`
    for await (const b of stream) {}
}

๐Ÿ™ Actual behavior

TS asserts b of type A even if stream implements AsyncIterable<B>.

๐Ÿ™‚ Expected behavior

b should be asserted to type B.

Additional information about the issue

Related issue #36153 discussed adding a type helper ForAwaitable for types support either sync or async iteration. However, the OP does not cover the issue that TS should prefer AsyncIterable<T> in async for loop when possible.

This is a caching issue: TS playground