diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a53c1841b6ef4..5a478c52b9e65 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -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 }; diff --git a/tests/baselines/reference/unresolvableSelfReferencingAwaitedUnion.errors.txt b/tests/baselines/reference/unresolvableSelfReferencingAwaitedUnion.errors.txt new file mode 100644 index 0000000000000..7d7ad42c4d034 --- /dev/null +++ b/tests/baselines/reference/unresolvableSelfReferencingAwaitedUnion.errors.txt @@ -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; + + type SimpleType = string | Promise; + + 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[]; + + 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. + } + \ No newline at end of file diff --git a/tests/baselines/reference/unresolvableSelfReferencingAwaitedUnion.symbols b/tests/baselines/reference/unresolvableSelfReferencingAwaitedUnion.symbols new file mode 100644 index 0000000000000..624a339e73229 --- /dev/null +++ b/tests/baselines/reference/unresolvableSelfReferencingAwaitedUnion.symbols @@ -0,0 +1,40 @@ +=== tests/cases/compiler/unresolvableSelfReferencingAwaitedUnion.ts === +// repro #49646 + +type EnvFunction = () => 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 : 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 : 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)) +} + diff --git a/tests/baselines/reference/unresolvableSelfReferencingAwaitedUnion.types b/tests/baselines/reference/unresolvableSelfReferencingAwaitedUnion.types new file mode 100644 index 0000000000000..521bfa461e573 --- /dev/null +++ b/tests/baselines/reference/unresolvableSelfReferencingAwaitedUnion.types @@ -0,0 +1,32 @@ +=== tests/cases/compiler/unresolvableSelfReferencingAwaitedUnion.ts === +// repro #49646 + +type EnvFunction = () => T; +>EnvFunction : () => T + +type SimpleType = string | Promise; +>SimpleType : string | Promise + +declare const simple: SimpleType; +>simple : SimpleType + +const env: EnvFunction = () => simple; +>env : EnvFunction +>() => simple : () => SimpleType +>simple : SimpleType + +// repro #49723 + +type T1 = 1 | Promise | T1[]; +>T1 : 1 | Promise | T1[] + +export async function myFunction(param: T1) { +>myFunction : (param: T1) => Promise +>param : T1 + + const awaited = await param +>awaited : 1 | T1[] +>await param : 1 | T1[] +>param : T1 +} + diff --git a/tests/cases/compiler/unresolvableSelfReferencingAwaitedUnion.ts b/tests/cases/compiler/unresolvableSelfReferencingAwaitedUnion.ts new file mode 100644 index 0000000000000..f179114ae419e --- /dev/null +++ b/tests/cases/compiler/unresolvableSelfReferencingAwaitedUnion.ts @@ -0,0 +1,19 @@ +// @noEmit: true + +// repro #49646 + +type EnvFunction = () => T; + +type SimpleType = string | Promise; + +declare const simple: SimpleType; + +const env: EnvFunction = () => simple; + +// repro #49723 + +type T1 = 1 | Promise | T1[]; + +export async function myFunction(param: T1) { + const awaited = await param +}