diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 17f2c0d1561..91346429b17 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -38376,7 +38376,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const globalGeneratorType = resolver.getGlobalGeneratorType(/*reportErrors*/ false); yieldType = resolver.resolveIterationType(yieldType, /*errorNode*/ undefined) || unknownType; returnType = resolver.resolveIterationType(returnType, /*errorNode*/ undefined) || unknownType; - nextType = resolver.resolveIterationType(nextType, /*errorNode*/ undefined) || unknownType; if (globalGeneratorType === emptyGenericType) { // Fall back to the global IterableIterator type. const globalIterableIteratorType = resolver.getGlobalIterableIteratorType(/*reportErrors*/ false); @@ -40287,9 +40286,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const iterationTypes = returnType && getIterationTypesOfGeneratorFunctionReturnType(returnType, isAsync); const signatureYieldType = iterationTypes && iterationTypes.yieldType || anyType; const signatureNextType = iterationTypes && iterationTypes.nextType || anyType; - const resolvedSignatureNextType = isAsync ? getAwaitedType(signatureNextType) || anyType : signatureNextType; const yieldExpressionType = node.expression ? checkExpression(node.expression) : undefinedWideningType; - const yieldedType = getYieldedTypeOfYieldExpression(node, yieldExpressionType, resolvedSignatureNextType, isAsync); + const yieldedType = getYieldedTypeOfYieldExpression(node, yieldExpressionType, signatureNextType, isAsync); if (returnType && yieldedType) { checkTypeAssignableToAndOptionallyElaborate(yieldedType, signatureYieldType, node.expression || node, node.expression); } diff --git a/tests/baselines/reference/asyncGeneratorPromiseNextType.symbols b/tests/baselines/reference/asyncGeneratorPromiseNextType.symbols new file mode 100644 index 00000000000..a853c42452e --- /dev/null +++ b/tests/baselines/reference/asyncGeneratorPromiseNextType.symbols @@ -0,0 +1,121 @@ +//// [tests/cases/conformance/asyncGenerators/asyncGeneratorPromiseNextType.ts] //// + +=== asyncGeneratorPromiseNextType.ts === +// https://github.com/microsoft/TypeScript/issues/44808 + +type Result = {message: string} +>Result : Symbol(Result, Decl(asyncGeneratorPromiseNextType.ts, 0, 0)) +>message : Symbol(message, Decl(asyncGeneratorPromiseNextType.ts, 2, 15)) + +async function *saverGen(): AsyncGenerator | undefined> { +>saverGen : Symbol(saverGen, Decl(asyncGeneratorPromiseNextType.ts, 2, 31)) +>AsyncGenerator : Symbol(AsyncGenerator, Decl(lib.es2018.asyncgenerator.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, --, --)) +>Result : Symbol(Result, Decl(asyncGeneratorPromiseNextType.ts, 0, 0)) + + let pending: Promise[] = []; +>pending : Symbol(pending, Decl(asyncGeneratorPromiseNextType.ts, 5, 7)) +>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, --, --)) +>Result : Symbol(Result, Decl(asyncGeneratorPromiseNextType.ts, 0, 0)) + + while (true) { + const p: Promise | undefined = yield; +>p : Symbol(p, Decl(asyncGeneratorPromiseNextType.ts, 7, 13)) +>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, --, --)) +>Result : Symbol(Result, Decl(asyncGeneratorPromiseNextType.ts, 0, 0)) + + if (p != null) +>p : Symbol(p, Decl(asyncGeneratorPromiseNextType.ts, 7, 13)) + + pending.push(p); +>pending.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>pending : Symbol(pending, Decl(asyncGeneratorPromiseNextType.ts, 5, 7)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>p : Symbol(p, Decl(asyncGeneratorPromiseNextType.ts, 7, 13)) + + else { + const results = await Promise.all(pending); +>results : Symbol(results, Decl(asyncGeneratorPromiseNextType.ts, 11, 17)) +>Promise.all : Symbol(PromiseConstructor.all, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.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, --, --)) +>all : Symbol(PromiseConstructor.all, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>pending : Symbol(pending, Decl(asyncGeneratorPromiseNextType.ts, 5, 7)) + + pending = []; +>pending : Symbol(pending, Decl(asyncGeneratorPromiseNextType.ts, 5, 7)) + + console.log('Storing...'); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) + + await storeResults(results); +>storeResults : Symbol(storeResults, Decl(asyncGeneratorPromiseNextType.ts, 17, 1)) +>results : Symbol(results, Decl(asyncGeneratorPromiseNextType.ts, 11, 17)) + } + } +} + +function storeResults(results: Result[]) { +>storeResults : Symbol(storeResults, Decl(asyncGeneratorPromiseNextType.ts, 17, 1)) +>results : Symbol(results, Decl(asyncGeneratorPromiseNextType.ts, 19, 22)) +>Result : Symbol(Result, Decl(asyncGeneratorPromiseNextType.ts, 0, 0)) + + console.log(results); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>results : Symbol(results, Decl(asyncGeneratorPromiseNextType.ts, 19, 22)) + + return Promise.resolve(); +>Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.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, --, --)) +>resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +} + +async function *saverGen2() { +>saverGen2 : Symbol(saverGen2, Decl(asyncGeneratorPromiseNextType.ts, 22, 1)) + + let pending: Promise[] = []; +>pending : Symbol(pending, Decl(asyncGeneratorPromiseNextType.ts, 25, 7)) +>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, --, --)) +>Result : Symbol(Result, Decl(asyncGeneratorPromiseNextType.ts, 0, 0)) + + while (true) { + const p: Promise | undefined = yield; +>p : Symbol(p, Decl(asyncGeneratorPromiseNextType.ts, 27, 13)) +>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, --, --)) +>Result : Symbol(Result, Decl(asyncGeneratorPromiseNextType.ts, 0, 0)) + + if (p != null) +>p : Symbol(p, Decl(asyncGeneratorPromiseNextType.ts, 27, 13)) + + pending.push(p); +>pending.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>pending : Symbol(pending, Decl(asyncGeneratorPromiseNextType.ts, 25, 7)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>p : Symbol(p, Decl(asyncGeneratorPromiseNextType.ts, 27, 13)) + + else { + const results = await Promise.all(pending); +>results : Symbol(results, Decl(asyncGeneratorPromiseNextType.ts, 31, 17)) +>Promise.all : Symbol(PromiseConstructor.all, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.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, --, --)) +>all : Symbol(PromiseConstructor.all, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>pending : Symbol(pending, Decl(asyncGeneratorPromiseNextType.ts, 25, 7)) + + pending = []; +>pending : Symbol(pending, Decl(asyncGeneratorPromiseNextType.ts, 25, 7)) + + console.log('Storing...'); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) + + await storeResults(results); +>storeResults : Symbol(storeResults, Decl(asyncGeneratorPromiseNextType.ts, 17, 1)) +>results : Symbol(results, Decl(asyncGeneratorPromiseNextType.ts, 31, 17)) + } + } +} + diff --git a/tests/baselines/reference/asyncGeneratorPromiseNextType.types b/tests/baselines/reference/asyncGeneratorPromiseNextType.types new file mode 100644 index 00000000000..04df59c42c6 --- /dev/null +++ b/tests/baselines/reference/asyncGeneratorPromiseNextType.types @@ -0,0 +1,215 @@ +//// [tests/cases/conformance/asyncGenerators/asyncGeneratorPromiseNextType.ts] //// + +=== asyncGeneratorPromiseNextType.ts === +// https://github.com/microsoft/TypeScript/issues/44808 + +type Result = {message: string} +>Result : Result +> : ^^^^^^ +>message : string +> : ^^^^^^ + +async function *saverGen(): AsyncGenerator | undefined> { +>saverGen : () => AsyncGenerator | undefined> +> : ^^^^^^ + + let pending: Promise[] = []; +>pending : Promise[] +> : ^^^^^^^^^^^^^^^^^ +>[] : never[] +> : ^^^^^^^ + + while (true) { +>true : true +> : ^^^^ + + const p: Promise | undefined = yield; +>p : Promise | undefined +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>yield : Promise | undefined +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + if (p != null) +>p != null : boolean +> : ^^^^^^^ +>p : Promise | undefined +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + pending.push(p); +>pending.push(p) : number +> : ^^^^^^ +>pending.push : (...items: Promise[]) => number +> : ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^ +>pending : Promise[] +> : ^^^^^^^^^^^^^^^^^ +>push : (...items: Promise[]) => number +> : ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^ +>p : Promise +> : ^^^^^^^^^^^^^^^ + + else { + const results = await Promise.all(pending); +>results : Result[] +> : ^^^^^^^^ +>await Promise.all(pending) : Result[] +> : ^^^^^^^^ +>Promise.all(pending) : Promise +> : ^^^^^^^^^^^^^^^^^ +>Promise.all : { (values: Iterable>): Promise[]>; (values: T): Promise<{ -readonly [P in keyof T]: Awaited; }>; } +> : ^^^ ^^ ^^ ^^^ ^^^ ^^^^^^^^^ ^^ ^^ ^^^ ^^^ +>Promise : PromiseConstructor +> : ^^^^^^^^^^^^^^^^^^ +>all : { (values: Iterable>): Promise[]>; (values: T): Promise<{ -readonly [P in keyof T]: Awaited; }>; } +> : ^^^ ^^ ^^ ^^^ ^^^ ^^^^^^^^^ ^^ ^^ ^^^ ^^^ +>pending : Promise[] +> : ^^^^^^^^^^^^^^^^^ + + pending = []; +>pending = [] : never[] +> : ^^^^^^^ +>pending : Promise[] +> : ^^^^^^^^^^^^^^^^^ +>[] : never[] +> : ^^^^^^^ + + console.log('Storing...'); +>console.log('Storing...') : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>'Storing...' : "Storing..." +> : ^^^^^^^^^^^^ + + await storeResults(results); +>await storeResults(results) : void +> : ^^^^ +>storeResults(results) : Promise +> : ^^^^^^^^^^^^^ +>storeResults : (results: Result[]) => Promise +> : ^ ^^ ^^^^^^^^^^^^^^^^^^ +>results : Result[] +> : ^^^^^^^^ + } + } +} + +function storeResults(results: Result[]) { +>storeResults : (results: Result[]) => Promise +> : ^ ^^ ^^^^^^^^^^^^^^^^^^ +>results : Result[] +> : ^^^^^^^^ + + console.log(results); +>console.log(results) : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>results : Result[] +> : ^^^^^^^^ + + return Promise.resolve(); +>Promise.resolve() : Promise +> : ^^^^^^^^^^^^^ +>Promise.resolve : { (): Promise; (value: T): Promise>; (value: T | PromiseLike): Promise>; } +> : ^^^^^^ ^^^ ^^ ^^ ^^^ ^^^ ^^ ^^ ^^^ ^^^ +>Promise : PromiseConstructor +> : ^^^^^^^^^^^^^^^^^^ +>resolve : { (): Promise; (value: T): Promise>; (value: T | PromiseLike): Promise>; } +> : ^^^^^^ ^^^ ^^ ^^ ^^^ ^^^ ^^ ^^ ^^^ ^^^ +} + +async function *saverGen2() { +>saverGen2 : () => AsyncGenerator | undefined> +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + let pending: Promise[] = []; +>pending : Promise[] +> : ^^^^^^^^^^^^^^^^^ +>[] : never[] +> : ^^^^^^^ + + while (true) { +>true : true +> : ^^^^ + + const p: Promise | undefined = yield; +>p : Promise | undefined +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>yield : any + + if (p != null) +>p != null : boolean +> : ^^^^^^^ +>p : Promise | undefined +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + pending.push(p); +>pending.push(p) : number +> : ^^^^^^ +>pending.push : (...items: Promise[]) => number +> : ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^ +>pending : Promise[] +> : ^^^^^^^^^^^^^^^^^ +>push : (...items: Promise[]) => number +> : ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^ +>p : Promise +> : ^^^^^^^^^^^^^^^ + + else { + const results = await Promise.all(pending); +>results : Result[] +> : ^^^^^^^^ +>await Promise.all(pending) : Result[] +> : ^^^^^^^^ +>Promise.all(pending) : Promise +> : ^^^^^^^^^^^^^^^^^ +>Promise.all : { (values: Iterable>): Promise[]>; (values: T): Promise<{ -readonly [P in keyof T]: Awaited; }>; } +> : ^^^ ^^ ^^ ^^^ ^^^ ^^^^^^^^^ ^^ ^^ ^^^ ^^^ +>Promise : PromiseConstructor +> : ^^^^^^^^^^^^^^^^^^ +>all : { (values: Iterable>): Promise[]>; (values: T): Promise<{ -readonly [P in keyof T]: Awaited; }>; } +> : ^^^ ^^ ^^ ^^^ ^^^ ^^^^^^^^^ ^^ ^^ ^^^ ^^^ +>pending : Promise[] +> : ^^^^^^^^^^^^^^^^^ + + pending = []; +>pending = [] : never[] +> : ^^^^^^^ +>pending : Promise[] +> : ^^^^^^^^^^^^^^^^^ +>[] : never[] +> : ^^^^^^^ + + console.log('Storing...'); +>console.log('Storing...') : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>'Storing...' : "Storing..." +> : ^^^^^^^^^^^^ + + await storeResults(results); +>await storeResults(results) : void +> : ^^^^ +>storeResults(results) : Promise +> : ^^^^^^^^^^^^^ +>storeResults : (results: Result[]) => Promise +> : ^ ^^ ^^^^^^^^^^^^^^^^^^ +>results : Result[] +> : ^^^^^^^^ + } + } +} + diff --git a/tests/cases/conformance/asyncGenerators/asyncGeneratorPromiseNextType.ts b/tests/cases/conformance/asyncGenerators/asyncGeneratorPromiseNextType.ts new file mode 100644 index 00000000000..dba96834a10 --- /dev/null +++ b/tests/cases/conformance/asyncGenerators/asyncGeneratorPromiseNextType.ts @@ -0,0 +1,42 @@ +// @target: esnext +// @strict: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/44808 + +type Result = {message: string} + +async function *saverGen(): AsyncGenerator | undefined> { + let pending: Promise[] = []; + while (true) { + const p: Promise | undefined = 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(); +} + +async function *saverGen2() { + let pending: Promise[] = []; + while (true) { + const p: Promise | undefined = yield; + if (p != null) + pending.push(p); + else { + const results = await Promise.all(pending); + pending = []; + console.log('Storing...'); + await storeResults(results); + } + } +}