diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 019f6bc6307e4..79383a6697caf 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -25260,14 +25260,18 @@ namespace ts { if (allowSyncIterables) { if (typeAsIterable.iteratedTypeOfIterable) { - return typeAsIterable.iteratedTypeOfIterable; + return allowAsyncIterables + ? typeAsIterable.iteratedTypeOfAsyncIterable = getAwaitedType(typeAsIterable.iteratedTypeOfIterable) + : typeAsIterable.iteratedTypeOfIterable; } // As an optimization, if the type is an instantiation of the global `Iterable` or // `IterableIterator` then just grab its type argument. if (isReferenceToType(type, getGlobalIterableType(/*reportErrors*/ false)) || isReferenceToType(type, getGlobalIterableIteratorType(/*reportErrors*/ false))) { - return typeAsIterable.iteratedTypeOfIterable = (type).typeArguments![0]; + return allowAsyncIterables + ? typeAsIterable.iteratedTypeOfAsyncIterable = getAwaitedType((type).typeArguments![0]) + : typeAsIterable.iteratedTypeOfIterable = (type).typeArguments![0]; } } @@ -25298,9 +25302,11 @@ namespace ts { : createIterableType(iteratedType), errorNode); } - return asyncMethodType - ? typeAsIterable.iteratedTypeOfAsyncIterable = iteratedType - : typeAsIterable.iteratedTypeOfIterable = iteratedType; + if (iteratedType) { + return allowAsyncIterables + ? typeAsIterable.iteratedTypeOfAsyncIterable = asyncMethodType ? iteratedType : getAwaitedType(iteratedType) + : typeAsIterable.iteratedTypeOfIterable = iteratedType; + } } } diff --git a/tests/baselines/reference/types.forAwait.esnext.1.symbols b/tests/baselines/reference/types.forAwait.esnext.1.symbols index 286f0a8555c54..c3c10c42109d6 100644 --- a/tests/baselines/reference/types.forAwait.esnext.1.symbols +++ b/tests/baselines/reference/types.forAwait.esnext.1.symbols @@ -7,49 +7,70 @@ declare const iterable: Iterable; >iterable : Symbol(iterable, Decl(types.forAwait.esnext.1.ts, 1, 13)) >Iterable : Symbol(Iterable, Decl(lib.es2015.iterable.d.ts, --, --)) +declare const iterableOfPromise: Iterable>; +>iterableOfPromise : Symbol(iterableOfPromise, Decl(types.forAwait.esnext.1.ts, 2, 13)) +>Iterable : Symbol(Iterable, Decl(lib.es2015.iterable.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) + async function f1() { ->f1 : Symbol(f1, Decl(types.forAwait.esnext.1.ts, 1, 41)) +>f1 : Symbol(f1, Decl(types.forAwait.esnext.1.ts, 2, 59)) let y: number; ->y : Symbol(y, Decl(types.forAwait.esnext.1.ts, 3, 7)) +>y : Symbol(y, Decl(types.forAwait.esnext.1.ts, 4, 7)) for await (const x of asyncIterable) { ->x : Symbol(x, Decl(types.forAwait.esnext.1.ts, 4, 20)) +>x : Symbol(x, Decl(types.forAwait.esnext.1.ts, 5, 20)) >asyncIterable : Symbol(asyncIterable, Decl(types.forAwait.esnext.1.ts, 0, 13)) } for await (const x of iterable) { ->x : Symbol(x, Decl(types.forAwait.esnext.1.ts, 6, 20)) +>x : Symbol(x, Decl(types.forAwait.esnext.1.ts, 7, 20)) >iterable : Symbol(iterable, Decl(types.forAwait.esnext.1.ts, 1, 13)) + } + for await (const x of iterableOfPromise) { +>x : Symbol(x, Decl(types.forAwait.esnext.1.ts, 9, 20)) +>iterableOfPromise : Symbol(iterableOfPromise, Decl(types.forAwait.esnext.1.ts, 2, 13)) } for await (y of asyncIterable) { ->y : Symbol(y, Decl(types.forAwait.esnext.1.ts, 3, 7)) +>y : Symbol(y, Decl(types.forAwait.esnext.1.ts, 4, 7)) >asyncIterable : Symbol(asyncIterable, Decl(types.forAwait.esnext.1.ts, 0, 13)) } for await (y of iterable) { ->y : Symbol(y, Decl(types.forAwait.esnext.1.ts, 3, 7)) +>y : Symbol(y, Decl(types.forAwait.esnext.1.ts, 4, 7)) >iterable : Symbol(iterable, Decl(types.forAwait.esnext.1.ts, 1, 13)) } + for await (y of iterableOfPromise) { +>y : Symbol(y, Decl(types.forAwait.esnext.1.ts, 4, 7)) +>iterableOfPromise : Symbol(iterableOfPromise, Decl(types.forAwait.esnext.1.ts, 2, 13)) + } } async function * f2() { ->f2 : Symbol(f2, Decl(types.forAwait.esnext.1.ts, 12, 1)) +>f2 : Symbol(f2, Decl(types.forAwait.esnext.1.ts, 17, 1)) let y: number; ->y : Symbol(y, Decl(types.forAwait.esnext.1.ts, 14, 7)) +>y : Symbol(y, Decl(types.forAwait.esnext.1.ts, 19, 7)) for await (const x of asyncIterable) { ->x : Symbol(x, Decl(types.forAwait.esnext.1.ts, 15, 20)) +>x : Symbol(x, Decl(types.forAwait.esnext.1.ts, 20, 20)) >asyncIterable : Symbol(asyncIterable, Decl(types.forAwait.esnext.1.ts, 0, 13)) } for await (const x of iterable) { ->x : Symbol(x, Decl(types.forAwait.esnext.1.ts, 17, 20)) +>x : Symbol(x, Decl(types.forAwait.esnext.1.ts, 22, 20)) >iterable : Symbol(iterable, Decl(types.forAwait.esnext.1.ts, 1, 13)) + } + for await (const x of iterableOfPromise) { +>x : Symbol(x, Decl(types.forAwait.esnext.1.ts, 24, 20)) +>iterableOfPromise : Symbol(iterableOfPromise, Decl(types.forAwait.esnext.1.ts, 2, 13)) } for await (y of asyncIterable) { ->y : Symbol(y, Decl(types.forAwait.esnext.1.ts, 14, 7)) +>y : Symbol(y, Decl(types.forAwait.esnext.1.ts, 19, 7)) >asyncIterable : Symbol(asyncIterable, Decl(types.forAwait.esnext.1.ts, 0, 13)) } for await (y of iterable) { ->y : Symbol(y, Decl(types.forAwait.esnext.1.ts, 14, 7)) +>y : Symbol(y, Decl(types.forAwait.esnext.1.ts, 19, 7)) >iterable : Symbol(iterable, Decl(types.forAwait.esnext.1.ts, 1, 13)) } + for await (y of iterableOfPromise) { +>y : Symbol(y, Decl(types.forAwait.esnext.1.ts, 19, 7)) +>iterableOfPromise : Symbol(iterableOfPromise, Decl(types.forAwait.esnext.1.ts, 2, 13)) + } } diff --git a/tests/baselines/reference/types.forAwait.esnext.1.types b/tests/baselines/reference/types.forAwait.esnext.1.types index f001b39a071e9..69403b40593cd 100644 --- a/tests/baselines/reference/types.forAwait.esnext.1.types +++ b/tests/baselines/reference/types.forAwait.esnext.1.types @@ -5,6 +5,9 @@ declare const asyncIterable: AsyncIterable; declare const iterable: Iterable; >iterable : Iterable +declare const iterableOfPromise: Iterable>; +>iterableOfPromise : Iterable> + async function f1() { >f1 : () => Promise @@ -18,6 +21,10 @@ async function f1() { for await (const x of iterable) { >x : number >iterable : Iterable + } + for await (const x of iterableOfPromise) { +>x : number +>iterableOfPromise : Iterable> } for await (y of asyncIterable) { >y : number @@ -27,6 +34,10 @@ async function f1() { >y : number >iterable : Iterable } + for await (y of iterableOfPromise) { +>y : number +>iterableOfPromise : Iterable> + } } async function * f2() { >f2 : () => AsyncIterableIterator @@ -41,6 +52,10 @@ async function * f2() { for await (const x of iterable) { >x : number >iterable : Iterable + } + for await (const x of iterableOfPromise) { +>x : number +>iterableOfPromise : Iterable> } for await (y of asyncIterable) { >y : number @@ -50,4 +65,8 @@ async function * f2() { >y : number >iterable : Iterable } + for await (y of iterableOfPromise) { +>y : number +>iterableOfPromise : Iterable> + } } diff --git a/tests/cases/conformance/types/forAwait/types.forAwait.esnext.1.ts b/tests/cases/conformance/types/forAwait/types.forAwait.esnext.1.ts index 4537e09a048b0..8b5157250b8b9 100644 --- a/tests/cases/conformance/types/forAwait/types.forAwait.esnext.1.ts +++ b/tests/cases/conformance/types/forAwait/types.forAwait.esnext.1.ts @@ -3,16 +3,21 @@ // @noEmit: true declare const asyncIterable: AsyncIterable; declare const iterable: Iterable; +declare const iterableOfPromise: Iterable>; async function f1() { let y: number; for await (const x of asyncIterable) { } for await (const x of iterable) { } + for await (const x of iterableOfPromise) { + } for await (y of asyncIterable) { } for await (y of iterable) { } + for await (y of iterableOfPromise) { + } } async function * f2() { let y: number; @@ -20,8 +25,12 @@ async function * f2() { } for await (const x of iterable) { } + for await (const x of iterableOfPromise) { + } for await (y of asyncIterable) { } for await (y of iterable) { } + for await (y of iterableOfPromise) { + } } \ No newline at end of file