Fixed an issue with self-referential awaited union (#49677)

This commit is contained in:
Mateusz Burzyński 2022-06-29 22:01:36 +02:00 committed by GitHub
parent 52f4055174
commit bd11ce2aeb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 134 additions and 1 deletions

View File

@ -36625,8 +36625,20 @@ namespace ts {
// For a union, get a union of the awaited types of each constituent.
if (type.flags & TypeFlags.Union) {
if (awaitedTypeStack.lastIndexOf(type.id) >= 0) {
if (errorNode) {
error(errorNode, Diagnostics.Type_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method);
}
return undefined;
}
const mapper = errorNode ? (constituentType: Type) => getAwaitedTypeNoAlias(constituentType, errorNode, diagnosticMessage, arg0) : getAwaitedTypeNoAlias;
return typeAsAwaitable.awaitedTypeOfType = mapType(type, mapper);
awaitedTypeStack.push(type.id);
const mapped = mapType(type, mapper);
awaitedTypeStack.pop();
return typeAsAwaitable.awaitedTypeOfType = mapped;
}
const thisTypeForErrorOut: { value: Type | undefined } = { value: undefined };

View File

@ -0,0 +1,30 @@
tests/cases/compiler/unresolvableSelfReferencingAwaitedUnion.ts(9,32): error TS2322: Type 'SimpleType' is not assignable to type 'T'.
'T' could be instantiated with an arbitrary type which could be unrelated to 'SimpleType'.
tests/cases/compiler/unresolvableSelfReferencingAwaitedUnion.ts(16,19): error TS1062: Type is referenced directly or indirectly in the fulfillment callback of its own 'then' method.
==== tests/cases/compiler/unresolvableSelfReferencingAwaitedUnion.ts (2 errors) ====
// repro #49646
type EnvFunction = <T>() => T;
type SimpleType = string | Promise<SimpleType>;
declare const simple: SimpleType;
const env: EnvFunction = () => simple;
~~~~~~
!!! error TS2322: Type 'SimpleType' is not assignable to type 'T'.
!!! error TS2322: 'T' could be instantiated with an arbitrary type which could be unrelated to 'SimpleType'.
!!! related TS6502 tests/cases/compiler/unresolvableSelfReferencingAwaitedUnion.ts:3:20: The expected type comes from the return type of this signature.
// repro #49723
type T1 = 1 | Promise<T1> | T1[];
export async function myFunction(param: T1) {
const awaited = await param
~~~~~~~~~~~
!!! error TS1062: Type is referenced directly or indirectly in the fulfillment callback of its own 'then' method.
}

View File

@ -0,0 +1,40 @@
=== tests/cases/compiler/unresolvableSelfReferencingAwaitedUnion.ts ===
// repro #49646
type EnvFunction = <T>() => T;
>EnvFunction : Symbol(EnvFunction, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 0, 0))
>T : Symbol(T, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 2, 20))
>T : Symbol(T, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 2, 20))
type SimpleType = string | Promise<SimpleType>;
>SimpleType : Symbol(SimpleType, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 2, 30))
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --))
>SimpleType : Symbol(SimpleType, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 2, 30))
declare const simple: SimpleType;
>simple : Symbol(simple, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 6, 13))
>SimpleType : Symbol(SimpleType, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 2, 30))
const env: EnvFunction = () => simple;
>env : Symbol(env, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 8, 5))
>EnvFunction : Symbol(EnvFunction, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 0, 0))
>simple : Symbol(simple, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 6, 13))
// repro #49723
type T1 = 1 | Promise<T1> | T1[];
>T1 : Symbol(T1, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 8, 38))
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --))
>T1 : Symbol(T1, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 8, 38))
>T1 : Symbol(T1, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 8, 38))
export async function myFunction(param: T1) {
>myFunction : Symbol(myFunction, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 12, 33))
>param : Symbol(param, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 14, 33))
>T1 : Symbol(T1, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 8, 38))
const awaited = await param
>awaited : Symbol(awaited, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 15, 7))
>param : Symbol(param, Decl(unresolvableSelfReferencingAwaitedUnion.ts, 14, 33))
}

View File

@ -0,0 +1,32 @@
=== tests/cases/compiler/unresolvableSelfReferencingAwaitedUnion.ts ===
// repro #49646
type EnvFunction = <T>() => T;
>EnvFunction : <T>() => T
type SimpleType = string | Promise<SimpleType>;
>SimpleType : string | Promise<SimpleType>
declare const simple: SimpleType;
>simple : SimpleType
const env: EnvFunction = () => simple;
>env : EnvFunction
>() => simple : () => SimpleType
>simple : SimpleType
// repro #49723
type T1 = 1 | Promise<T1> | T1[];
>T1 : 1 | Promise<T1> | T1[]
export async function myFunction(param: T1) {
>myFunction : (param: T1) => Promise<void>
>param : T1
const awaited = await param
>awaited : 1 | T1[]
>await param : 1 | T1[]
>param : T1
}

View File

@ -0,0 +1,19 @@
// @noEmit: true
// repro #49646
type EnvFunction = <T>() => T;
type SimpleType = string | Promise<SimpleType>;
declare const simple: SimpleType;
const env: EnvFunction = () => simple;
// repro #49723
type T1 = 1 | Promise<T1> | T1[];
export async function myFunction(param: T1) {
const awaited = await param
}