Skip to content

Commit bd11ce2

Browse files
authored
Fixed an issue with self-referential awaited union (#49677)
1 parent 52f4055 commit bd11ce2

5 files changed

+134
-1
lines changed

src/compiler/checker.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36625,8 +36625,20 @@ namespace ts {
3662536625

3662636626
// For a union, get a union of the awaited types of each constituent.
3662736627
if (type.flags & TypeFlags.Union) {
36628+
if (awaitedTypeStack.lastIndexOf(type.id) >= 0) {
36629+
if (errorNode) {
36630+
error(errorNode, Diagnostics.Type_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method);
36631+
}
36632+
return undefined;
36633+
}
36634+
3662836635
const mapper = errorNode ? (constituentType: Type) => getAwaitedTypeNoAlias(constituentType, errorNode, diagnosticMessage, arg0) : getAwaitedTypeNoAlias;
36629-
return typeAsAwaitable.awaitedTypeOfType = mapType(type, mapper);
36636+
36637+
awaitedTypeStack.push(type.id);
36638+
const mapped = mapType(type, mapper);
36639+
awaitedTypeStack.pop();
36640+
36641+
return typeAsAwaitable.awaitedTypeOfType = mapped;
3663036642
}
3663136643

3663236644
const thisTypeForErrorOut: { value: Type | undefined } = { value: undefined };
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
tests/cases/compiler/unresolvableSelfReferencingAwaitedUnion.ts(9,32): error TS2322: Type 'SimpleType' is not assignable to type 'T'.
2+
'T' could be instantiated with an arbitrary type which could be unrelated to 'SimpleType'.
3+
tests/cases/compiler/unresolvableSelfReferencingAwaitedUnion.ts(16,19): error TS1062: Type is referenced directly or indirectly in the fulfillment callback of its own 'then' method.
4+
5+
6+
==== tests/cases/compiler/unresolvableSelfReferencingAwaitedUnion.ts (2 errors) ====
7+
// repro #49646
8+
9+
type EnvFunction = <T>() => T;
10+
11+
type SimpleType = string | Promise<SimpleType>;
12+
13+
declare const simple: SimpleType;
14+
15+
const env: EnvFunction = () => simple;
16+
~~~~~~
17+
!!! error TS2322: Type 'SimpleType' is not assignable to type 'T'.
18+
!!! error TS2322: 'T' could be instantiated with an arbitrary type which could be unrelated to 'SimpleType'.
19+
!!! related TS6502 tests/cases/compiler/unresolvableSelfReferencingAwaitedUnion.ts:3:20: The expected type comes from the return type of this signature.
20+
21+
// repro #49723
22+
23+
type T1 = 1 | Promise<T1> | T1[];
24+
25+
export async function myFunction(param: T1) {
26+
const awaited = await param
27+
~~~~~~~~~~~
28+
!!! error TS1062: Type is referenced directly or indirectly in the fulfillment callback of its own 'then' method.
29+
}
30+
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
=== tests/cases/compiler/unresolvableSelfReferencingAwaitedUnion.ts ===
2+
// repro #49646
3+
4+
type EnvFunction = <T>() => T;
5+
>EnvFunction : Symbol(EnvFunction, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 0, 0))
6+
>T : Symbol(T, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 2, 20))
7+
>T : Symbol(T, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 2, 20))
8+
9+
type SimpleType = string | Promise<SimpleType>;
10+
>SimpleType : Symbol(SimpleType, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 2, 30))
11+
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --))
12+
>SimpleType : Symbol(SimpleType, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 2, 30))
13+
14+
declare const simple: SimpleType;
15+
>simple : Symbol(simple, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 6, 13))
16+
>SimpleType : Symbol(SimpleType, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 2, 30))
17+
18+
const env: EnvFunction = () => simple;
19+
>env : Symbol(env, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 8, 5))
20+
>EnvFunction : Symbol(EnvFunction, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 0, 0))
21+
>simple : Symbol(simple, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 6, 13))
22+
23+
// repro #49723
24+
25+
type T1 = 1 | Promise<T1> | T1[];
26+
>T1 : Symbol(T1, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 8, 38))
27+
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --))
28+
>T1 : Symbol(T1, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 8, 38))
29+
>T1 : Symbol(T1, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 8, 38))
30+
31+
export async function myFunction(param: T1) {
32+
>myFunction : Symbol(myFunction, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 12, 33))
33+
>param : Symbol(param, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 14, 33))
34+
>T1 : Symbol(T1, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 8, 38))
35+
36+
const awaited = await param
37+
>awaited : Symbol(awaited, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 15, 7))
38+
>param : Symbol(param, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 14, 33))
39+
}
40+
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
=== tests/cases/compiler/unresolvableSelfReferencingAwaitedUnion.ts ===
2+
// repro #49646
3+
4+
type EnvFunction = <T>() => T;
5+
>EnvFunction : <T>() => T
6+
7+
type SimpleType = string | Promise<SimpleType>;
8+
>SimpleType : string | Promise<SimpleType>
9+
10+
declare const simple: SimpleType;
11+
>simple : SimpleType
12+
13+
const env: EnvFunction = () => simple;
14+
>env : EnvFunction
15+
>() => simple : () => SimpleType
16+
>simple : SimpleType
17+
18+
// repro #49723
19+
20+
type T1 = 1 | Promise<T1> | T1[];
21+
>T1 : 1 | Promise<T1> | T1[]
22+
23+
export async function myFunction(param: T1) {
24+
>myFunction : (param: T1) => Promise<void>
25+
>param : T1
26+
27+
const awaited = await param
28+
>awaited : 1 | T1[]
29+
>await param : 1 | T1[]
30+
>param : T1
31+
}
32+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// @noEmit: true
2+
3+
// repro #49646
4+
5+
type EnvFunction = <T>() => T;
6+
7+
type SimpleType = string | Promise<SimpleType>;
8+
9+
declare const simple: SimpleType;
10+
11+
const env: EnvFunction = () => simple;
12+
13+
// repro #49723
14+
15+
type T1 = 1 | Promise<T1> | T1[];
16+
17+
export async function myFunction(param: T1) {
18+
const awaited = await param
19+
}

0 commit comments

Comments
 (0)