Do not get awaited type of AsyncGenerator TNext (#59644)

This commit is contained in:
Ron Buckton 2024-08-16 11:55:46 -04:00 committed by GitHub
parent 856e472104
commit 09a8522294
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 379 additions and 3 deletions

View File

@ -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);
}

View File

@ -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<void, void, Promise<Result> | 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<Result>[] = [];
>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<Result> | 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<Result>[] = [];
>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<Result> | 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))
}
}
}

View File

@ -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<void, void, Promise<Result> | undefined> {
>saverGen : () => AsyncGenerator<void, void, Promise<Result> | undefined>
> : ^^^^^^
let pending: Promise<Result>[] = [];
>pending : Promise<Result>[]
> : ^^^^^^^^^^^^^^^^^
>[] : never[]
> : ^^^^^^^
while (true) {
>true : true
> : ^^^^
const p: Promise<Result> | undefined = yield;
>p : Promise<Result> | undefined
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^
>yield : Promise<Result> | undefined
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^
if (p != null)
>p != null : boolean
> : ^^^^^^^
>p : Promise<Result> | undefined
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^
pending.push(p);
>pending.push(p) : number
> : ^^^^^^
>pending.push : (...items: Promise<Result>[]) => number
> : ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^
>pending : Promise<Result>[]
> : ^^^^^^^^^^^^^^^^^
>push : (...items: Promise<Result>[]) => number
> : ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^
>p : Promise<Result>
> : ^^^^^^^^^^^^^^^
else {
const results = await Promise.all(pending);
>results : Result[]
> : ^^^^^^^^
>await Promise.all(pending) : Result[]
> : ^^^^^^^^
>Promise.all(pending) : Promise<Result[]>
> : ^^^^^^^^^^^^^^^^^
>Promise.all : { <T>(values: Iterable<T | PromiseLike<T>>): Promise<Awaited<T>[]>; <T extends readonly unknown[] | []>(values: T): Promise<{ -readonly [P in keyof T]: Awaited<T[P]>; }>; }
> : ^^^ ^^ ^^ ^^^ ^^^ ^^^^^^^^^ ^^ ^^ ^^^ ^^^
>Promise : PromiseConstructor
> : ^^^^^^^^^^^^^^^^^^
>all : { <T>(values: Iterable<T | PromiseLike<T>>): Promise<Awaited<T>[]>; <T extends readonly unknown[] | []>(values: T): Promise<{ -readonly [P in keyof T]: Awaited<T[P]>; }>; }
> : ^^^ ^^ ^^ ^^^ ^^^ ^^^^^^^^^ ^^ ^^ ^^^ ^^^
>pending : Promise<Result>[]
> : ^^^^^^^^^^^^^^^^^
pending = [];
>pending = [] : never[]
> : ^^^^^^^
>pending : Promise<Result>[]
> : ^^^^^^^^^^^^^^^^^
>[] : 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<void>
> : ^^^^^^^^^^^^^
>storeResults : (results: Result[]) => Promise<void>
> : ^ ^^ ^^^^^^^^^^^^^^^^^^
>results : Result[]
> : ^^^^^^^^
}
}
}
function storeResults(results: Result[]) {
>storeResults : (results: Result[]) => Promise<void>
> : ^ ^^ ^^^^^^^^^^^^^^^^^^
>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<void>
> : ^^^^^^^^^^^^^
>Promise.resolve : { (): Promise<void>; <T>(value: T): Promise<Awaited<T>>; <T>(value: T | PromiseLike<T>): Promise<Awaited<T>>; }
> : ^^^^^^ ^^^ ^^ ^^ ^^^ ^^^ ^^ ^^ ^^^ ^^^
>Promise : PromiseConstructor
> : ^^^^^^^^^^^^^^^^^^
>resolve : { (): Promise<void>; <T>(value: T): Promise<Awaited<T>>; <T>(value: T | PromiseLike<T>): Promise<Awaited<T>>; }
> : ^^^^^^ ^^^ ^^ ^^ ^^^ ^^^ ^^ ^^ ^^^ ^^^
}
async function *saverGen2() {
>saverGen2 : () => AsyncGenerator<undefined, void, Promise<Result> | undefined>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
let pending: Promise<Result>[] = [];
>pending : Promise<Result>[]
> : ^^^^^^^^^^^^^^^^^
>[] : never[]
> : ^^^^^^^
while (true) {
>true : true
> : ^^^^
const p: Promise<Result> | undefined = yield;
>p : Promise<Result> | undefined
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^
>yield : any
if (p != null)
>p != null : boolean
> : ^^^^^^^
>p : Promise<Result> | undefined
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^
pending.push(p);
>pending.push(p) : number
> : ^^^^^^
>pending.push : (...items: Promise<Result>[]) => number
> : ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^
>pending : Promise<Result>[]
> : ^^^^^^^^^^^^^^^^^
>push : (...items: Promise<Result>[]) => number
> : ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^
>p : Promise<Result>
> : ^^^^^^^^^^^^^^^
else {
const results = await Promise.all(pending);
>results : Result[]
> : ^^^^^^^^
>await Promise.all(pending) : Result[]
> : ^^^^^^^^
>Promise.all(pending) : Promise<Result[]>
> : ^^^^^^^^^^^^^^^^^
>Promise.all : { <T>(values: Iterable<T | PromiseLike<T>>): Promise<Awaited<T>[]>; <T extends readonly unknown[] | []>(values: T): Promise<{ -readonly [P in keyof T]: Awaited<T[P]>; }>; }
> : ^^^ ^^ ^^ ^^^ ^^^ ^^^^^^^^^ ^^ ^^ ^^^ ^^^
>Promise : PromiseConstructor
> : ^^^^^^^^^^^^^^^^^^
>all : { <T>(values: Iterable<T | PromiseLike<T>>): Promise<Awaited<T>[]>; <T extends readonly unknown[] | []>(values: T): Promise<{ -readonly [P in keyof T]: Awaited<T[P]>; }>; }
> : ^^^ ^^ ^^ ^^^ ^^^ ^^^^^^^^^ ^^ ^^ ^^^ ^^^
>pending : Promise<Result>[]
> : ^^^^^^^^^^^^^^^^^
pending = [];
>pending = [] : never[]
> : ^^^^^^^
>pending : Promise<Result>[]
> : ^^^^^^^^^^^^^^^^^
>[] : 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<void>
> : ^^^^^^^^^^^^^
>storeResults : (results: Result[]) => Promise<void>
> : ^ ^^ ^^^^^^^^^^^^^^^^^^
>results : Result[]
> : ^^^^^^^^
}
}
}

View File

@ -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<void, void, Promise<Result> | undefined> {
let pending: Promise<Result>[] = [];
while (true) {
const p: Promise<Result> | 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<Result>[] = [];
while (true) {
const p: Promise<Result> | undefined = yield;
if (p != null)
pending.push(p);
else {
const results = await Promise.all(pending);
pending = [];
console.log('Storing...');
await storeResults(results);
}
}
}