Skip to content

Commit 09a8522

Browse files
authored
Do not get awaited type of AsyncGenerator TNext (microsoft#59644)
1 parent 856e472 commit 09a8522

File tree

4 files changed

+379
-3
lines changed

4 files changed

+379
-3
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38376,7 +38376,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3837638376
const globalGeneratorType = resolver.getGlobalGeneratorType(/*reportErrors*/ false);
3837738377
yieldType = resolver.resolveIterationType(yieldType, /*errorNode*/ undefined) || unknownType;
3837838378
returnType = resolver.resolveIterationType(returnType, /*errorNode*/ undefined) || unknownType;
38379-
nextType = resolver.resolveIterationType(nextType, /*errorNode*/ undefined) || unknownType;
3838038379
if (globalGeneratorType === emptyGenericType) {
3838138380
// Fall back to the global IterableIterator type.
3838238381
const globalIterableIteratorType = resolver.getGlobalIterableIteratorType(/*reportErrors*/ false);
@@ -40287,9 +40286,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4028740286
const iterationTypes = returnType && getIterationTypesOfGeneratorFunctionReturnType(returnType, isAsync);
4028840287
const signatureYieldType = iterationTypes && iterationTypes.yieldType || anyType;
4028940288
const signatureNextType = iterationTypes && iterationTypes.nextType || anyType;
40290-
const resolvedSignatureNextType = isAsync ? getAwaitedType(signatureNextType) || anyType : signatureNextType;
4029140289
const yieldExpressionType = node.expression ? checkExpression(node.expression) : undefinedWideningType;
40292-
const yieldedType = getYieldedTypeOfYieldExpression(node, yieldExpressionType, resolvedSignatureNextType, isAsync);
40290+
const yieldedType = getYieldedTypeOfYieldExpression(node, yieldExpressionType, signatureNextType, isAsync);
4029340291
if (returnType && yieldedType) {
4029440292
checkTypeAssignableToAndOptionallyElaborate(yieldedType, signatureYieldType, node.expression || node, node.expression);
4029540293
}
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
//// [tests/cases/conformance/asyncGenerators/asyncGeneratorPromiseNextType.ts] ////
2+
3+
=== asyncGeneratorPromiseNextType.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/44808
5+
6+
type Result = {message: string}
7+
>Result : Symbol(Result, Decl(asyncGeneratorPromiseNextType.ts, 0, 0))
8+
>message : Symbol(message, Decl(asyncGeneratorPromiseNextType.ts, 2, 15))
9+
10+
async function *saverGen(): AsyncGenerator<void, void, Promise<Result> | undefined> {
11+
>saverGen : Symbol(saverGen, Decl(asyncGeneratorPromiseNextType.ts, 2, 31))
12+
>AsyncGenerator : Symbol(AsyncGenerator, Decl(lib.es2018.asyncgenerator.d.ts, --, --))
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, --, --))
14+
>Result : Symbol(Result, Decl(asyncGeneratorPromiseNextType.ts, 0, 0))
15+
16+
let pending: Promise<Result>[] = [];
17+
>pending : Symbol(pending, Decl(asyncGeneratorPromiseNextType.ts, 5, 7))
18+
>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, --, --))
19+
>Result : Symbol(Result, Decl(asyncGeneratorPromiseNextType.ts, 0, 0))
20+
21+
while (true) {
22+
const p: Promise<Result> | undefined = yield;
23+
>p : Symbol(p, Decl(asyncGeneratorPromiseNextType.ts, 7, 13))
24+
>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, --, --))
25+
>Result : Symbol(Result, Decl(asyncGeneratorPromiseNextType.ts, 0, 0))
26+
27+
if (p != null)
28+
>p : Symbol(p, Decl(asyncGeneratorPromiseNextType.ts, 7, 13))
29+
30+
pending.push(p);
31+
>pending.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
32+
>pending : Symbol(pending, Decl(asyncGeneratorPromiseNextType.ts, 5, 7))
33+
>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
34+
>p : Symbol(p, Decl(asyncGeneratorPromiseNextType.ts, 7, 13))
35+
36+
else {
37+
const results = await Promise.all(pending);
38+
>results : Symbol(results, Decl(asyncGeneratorPromiseNextType.ts, 11, 17))
39+
>Promise.all : Symbol(PromiseConstructor.all, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
40+
>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, --, --))
41+
>all : Symbol(PromiseConstructor.all, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
42+
>pending : Symbol(pending, Decl(asyncGeneratorPromiseNextType.ts, 5, 7))
43+
44+
pending = [];
45+
>pending : Symbol(pending, Decl(asyncGeneratorPromiseNextType.ts, 5, 7))
46+
47+
console.log('Storing...');
48+
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
49+
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
50+
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
51+
52+
await storeResults(results);
53+
>storeResults : Symbol(storeResults, Decl(asyncGeneratorPromiseNextType.ts, 17, 1))
54+
>results : Symbol(results, Decl(asyncGeneratorPromiseNextType.ts, 11, 17))
55+
}
56+
}
57+
}
58+
59+
function storeResults(results: Result[]) {
60+
>storeResults : Symbol(storeResults, Decl(asyncGeneratorPromiseNextType.ts, 17, 1))
61+
>results : Symbol(results, Decl(asyncGeneratorPromiseNextType.ts, 19, 22))
62+
>Result : Symbol(Result, Decl(asyncGeneratorPromiseNextType.ts, 0, 0))
63+
64+
console.log(results);
65+
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
66+
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
67+
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
68+
>results : Symbol(results, Decl(asyncGeneratorPromiseNextType.ts, 19, 22))
69+
70+
return Promise.resolve();
71+
>Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
72+
>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, --, --))
73+
>resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
74+
}
75+
76+
async function *saverGen2() {
77+
>saverGen2 : Symbol(saverGen2, Decl(asyncGeneratorPromiseNextType.ts, 22, 1))
78+
79+
let pending: Promise<Result>[] = [];
80+
>pending : Symbol(pending, Decl(asyncGeneratorPromiseNextType.ts, 25, 7))
81+
>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, --, --))
82+
>Result : Symbol(Result, Decl(asyncGeneratorPromiseNextType.ts, 0, 0))
83+
84+
while (true) {
85+
const p: Promise<Result> | undefined = yield;
86+
>p : Symbol(p, Decl(asyncGeneratorPromiseNextType.ts, 27, 13))
87+
>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, --, --))
88+
>Result : Symbol(Result, Decl(asyncGeneratorPromiseNextType.ts, 0, 0))
89+
90+
if (p != null)
91+
>p : Symbol(p, Decl(asyncGeneratorPromiseNextType.ts, 27, 13))
92+
93+
pending.push(p);
94+
>pending.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
95+
>pending : Symbol(pending, Decl(asyncGeneratorPromiseNextType.ts, 25, 7))
96+
>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
97+
>p : Symbol(p, Decl(asyncGeneratorPromiseNextType.ts, 27, 13))
98+
99+
else {
100+
const results = await Promise.all(pending);
101+
>results : Symbol(results, Decl(asyncGeneratorPromiseNextType.ts, 31, 17))
102+
>Promise.all : Symbol(PromiseConstructor.all, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
103+
>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, --, --))
104+
>all : Symbol(PromiseConstructor.all, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
105+
>pending : Symbol(pending, Decl(asyncGeneratorPromiseNextType.ts, 25, 7))
106+
107+
pending = [];
108+
>pending : Symbol(pending, Decl(asyncGeneratorPromiseNextType.ts, 25, 7))
109+
110+
console.log('Storing...');
111+
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
112+
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
113+
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
114+
115+
await storeResults(results);
116+
>storeResults : Symbol(storeResults, Decl(asyncGeneratorPromiseNextType.ts, 17, 1))
117+
>results : Symbol(results, Decl(asyncGeneratorPromiseNextType.ts, 31, 17))
118+
}
119+
}
120+
}
121+
Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
//// [tests/cases/conformance/asyncGenerators/asyncGeneratorPromiseNextType.ts] ////
2+
3+
=== asyncGeneratorPromiseNextType.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/44808
5+
6+
type Result = {message: string}
7+
>Result : Result
8+
> : ^^^^^^
9+
>message : string
10+
> : ^^^^^^
11+
12+
async function *saverGen(): AsyncGenerator<void, void, Promise<Result> | undefined> {
13+
>saverGen : () => AsyncGenerator<void, void, Promise<Result> | undefined>
14+
> : ^^^^^^
15+
16+
let pending: Promise<Result>[] = [];
17+
>pending : Promise<Result>[]
18+
> : ^^^^^^^^^^^^^^^^^
19+
>[] : never[]
20+
> : ^^^^^^^
21+
22+
while (true) {
23+
>true : true
24+
> : ^^^^
25+
26+
const p: Promise<Result> | undefined = yield;
27+
>p : Promise<Result> | undefined
28+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^
29+
>yield : Promise<Result> | undefined
30+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^
31+
32+
if (p != null)
33+
>p != null : boolean
34+
> : ^^^^^^^
35+
>p : Promise<Result> | undefined
36+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^
37+
38+
pending.push(p);
39+
>pending.push(p) : number
40+
> : ^^^^^^
41+
>pending.push : (...items: Promise<Result>[]) => number
42+
> : ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^
43+
>pending : Promise<Result>[]
44+
> : ^^^^^^^^^^^^^^^^^
45+
>push : (...items: Promise<Result>[]) => number
46+
> : ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^
47+
>p : Promise<Result>
48+
> : ^^^^^^^^^^^^^^^
49+
50+
else {
51+
const results = await Promise.all(pending);
52+
>results : Result[]
53+
> : ^^^^^^^^
54+
>await Promise.all(pending) : Result[]
55+
> : ^^^^^^^^
56+
>Promise.all(pending) : Promise<Result[]>
57+
> : ^^^^^^^^^^^^^^^^^
58+
>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]>; }>; }
59+
> : ^^^ ^^ ^^ ^^^ ^^^ ^^^^^^^^^ ^^ ^^ ^^^ ^^^
60+
>Promise : PromiseConstructor
61+
> : ^^^^^^^^^^^^^^^^^^
62+
>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]>; }>; }
63+
> : ^^^ ^^ ^^ ^^^ ^^^ ^^^^^^^^^ ^^ ^^ ^^^ ^^^
64+
>pending : Promise<Result>[]
65+
> : ^^^^^^^^^^^^^^^^^
66+
67+
pending = [];
68+
>pending = [] : never[]
69+
> : ^^^^^^^
70+
>pending : Promise<Result>[]
71+
> : ^^^^^^^^^^^^^^^^^
72+
>[] : never[]
73+
> : ^^^^^^^
74+
75+
console.log('Storing...');
76+
>console.log('Storing...') : void
77+
> : ^^^^
78+
>console.log : (...data: any[]) => void
79+
> : ^^^^ ^^ ^^^^^
80+
>console : Console
81+
> : ^^^^^^^
82+
>log : (...data: any[]) => void
83+
> : ^^^^ ^^ ^^^^^
84+
>'Storing...' : "Storing..."
85+
> : ^^^^^^^^^^^^
86+
87+
await storeResults(results);
88+
>await storeResults(results) : void
89+
> : ^^^^
90+
>storeResults(results) : Promise<void>
91+
> : ^^^^^^^^^^^^^
92+
>storeResults : (results: Result[]) => Promise<void>
93+
> : ^ ^^ ^^^^^^^^^^^^^^^^^^
94+
>results : Result[]
95+
> : ^^^^^^^^
96+
}
97+
}
98+
}
99+
100+
function storeResults(results: Result[]) {
101+
>storeResults : (results: Result[]) => Promise<void>
102+
> : ^ ^^ ^^^^^^^^^^^^^^^^^^
103+
>results : Result[]
104+
> : ^^^^^^^^
105+
106+
console.log(results);
107+
>console.log(results) : void
108+
> : ^^^^
109+
>console.log : (...data: any[]) => void
110+
> : ^^^^ ^^ ^^^^^
111+
>console : Console
112+
> : ^^^^^^^
113+
>log : (...data: any[]) => void
114+
> : ^^^^ ^^ ^^^^^
115+
>results : Result[]
116+
> : ^^^^^^^^
117+
118+
return Promise.resolve();
119+
>Promise.resolve() : Promise<void>
120+
> : ^^^^^^^^^^^^^
121+
>Promise.resolve : { (): Promise<void>; <T>(value: T): Promise<Awaited<T>>; <T>(value: T | PromiseLike<T>): Promise<Awaited<T>>; }
122+
> : ^^^^^^ ^^^ ^^ ^^ ^^^ ^^^ ^^ ^^ ^^^ ^^^
123+
>Promise : PromiseConstructor
124+
> : ^^^^^^^^^^^^^^^^^^
125+
>resolve : { (): Promise<void>; <T>(value: T): Promise<Awaited<T>>; <T>(value: T | PromiseLike<T>): Promise<Awaited<T>>; }
126+
> : ^^^^^^ ^^^ ^^ ^^ ^^^ ^^^ ^^ ^^ ^^^ ^^^
127+
}
128+
129+
async function *saverGen2() {
130+
>saverGen2 : () => AsyncGenerator<undefined, void, Promise<Result> | undefined>
131+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
132+
133+
let pending: Promise<Result>[] = [];
134+
>pending : Promise<Result>[]
135+
> : ^^^^^^^^^^^^^^^^^
136+
>[] : never[]
137+
> : ^^^^^^^
138+
139+
while (true) {
140+
>true : true
141+
> : ^^^^
142+
143+
const p: Promise<Result> | undefined = yield;
144+
>p : Promise<Result> | undefined
145+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^
146+
>yield : any
147+
148+
if (p != null)
149+
>p != null : boolean
150+
> : ^^^^^^^
151+
>p : Promise<Result> | undefined
152+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^
153+
154+
pending.push(p);
155+
>pending.push(p) : number
156+
> : ^^^^^^
157+
>pending.push : (...items: Promise<Result>[]) => number
158+
> : ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^
159+
>pending : Promise<Result>[]
160+
> : ^^^^^^^^^^^^^^^^^
161+
>push : (...items: Promise<Result>[]) => number
162+
> : ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^
163+
>p : Promise<Result>
164+
> : ^^^^^^^^^^^^^^^
165+
166+
else {
167+
const results = await Promise.all(pending);
168+
>results : Result[]
169+
> : ^^^^^^^^
170+
>await Promise.all(pending) : Result[]
171+
> : ^^^^^^^^
172+
>Promise.all(pending) : Promise<Result[]>
173+
> : ^^^^^^^^^^^^^^^^^
174+
>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]>; }>; }
175+
> : ^^^ ^^ ^^ ^^^ ^^^ ^^^^^^^^^ ^^ ^^ ^^^ ^^^
176+
>Promise : PromiseConstructor
177+
> : ^^^^^^^^^^^^^^^^^^
178+
>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]>; }>; }
179+
> : ^^^ ^^ ^^ ^^^ ^^^ ^^^^^^^^^ ^^ ^^ ^^^ ^^^
180+
>pending : Promise<Result>[]
181+
> : ^^^^^^^^^^^^^^^^^
182+
183+
pending = [];
184+
>pending = [] : never[]
185+
> : ^^^^^^^
186+
>pending : Promise<Result>[]
187+
> : ^^^^^^^^^^^^^^^^^
188+
>[] : never[]
189+
> : ^^^^^^^
190+
191+
console.log('Storing...');
192+
>console.log('Storing...') : void
193+
> : ^^^^
194+
>console.log : (...data: any[]) => void
195+
> : ^^^^ ^^ ^^^^^
196+
>console : Console
197+
> : ^^^^^^^
198+
>log : (...data: any[]) => void
199+
> : ^^^^ ^^ ^^^^^
200+
>'Storing...' : "Storing..."
201+
> : ^^^^^^^^^^^^
202+
203+
await storeResults(results);
204+
>await storeResults(results) : void
205+
> : ^^^^
206+
>storeResults(results) : Promise<void>
207+
> : ^^^^^^^^^^^^^
208+
>storeResults : (results: Result[]) => Promise<void>
209+
> : ^ ^^ ^^^^^^^^^^^^^^^^^^
210+
>results : Result[]
211+
> : ^^^^^^^^
212+
}
213+
}
214+
}
215+
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// @target: esnext
2+
// @strict: true
3+
// @noEmit: true
4+
5+
// https://github.com/microsoft/TypeScript/issues/44808
6+
7+
type Result = {message: string}
8+
9+
async function *saverGen(): AsyncGenerator<void, void, Promise<Result> | undefined> {
10+
let pending: Promise<Result>[] = [];
11+
while (true) {
12+
const p: Promise<Result> | undefined = yield;
13+
if (p != null)
14+
pending.push(p);
15+
else {
16+
const results = await Promise.all(pending);
17+
pending = [];
18+
console.log('Storing...');
19+
await storeResults(results);
20+
}
21+
}
22+
}
23+
24+
function storeResults(results: Result[]) {
25+
console.log(results);
26+
return Promise.resolve();
27+
}
28+
29+
async function *saverGen2() {
30+
let pending: Promise<Result>[] = [];
31+
while (true) {
32+
const p: Promise<Result> | undefined = yield;
33+
if (p != null)
34+
pending.push(p);
35+
else {
36+
const results = await Promise.all(pending);
37+
pending = [];
38+
console.log('Storing...');
39+
await storeResults(results);
40+
}
41+
}
42+
}

0 commit comments

Comments
 (0)