From cd3bd5522b03e5da259c999a1093516b665fe786 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Fri, 15 Jul 2022 00:51:03 +0200 Subject: [PATCH] Fixed an issue with generic naked T not being allowed as async generator's return (#49023) --- src/compiler/checker.ts | 11 ++++++++--- ...syncGeneratorGenericNonWrappedReturn.symbols | 17 +++++++++++++++++ .../asyncGeneratorGenericNonWrappedReturn.types | 11 +++++++++++ .../asyncGeneratorGenericNonWrappedReturn.ts | 9 +++++++++ 4 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 tests/baselines/reference/asyncGeneratorGenericNonWrappedReturn.symbols create mode 100644 tests/baselines/reference/asyncGeneratorGenericNonWrappedReturn.types create mode 100644 tests/cases/conformance/generators/asyncGeneratorGenericNonWrappedReturn.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7a708089444..5b870a90d9f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -39273,9 +39273,14 @@ namespace ts { function unwrapReturnType(returnType: Type, functionFlags: FunctionFlags) { const isGenerator = !!(functionFlags & FunctionFlags.Generator); const isAsync = !!(functionFlags & FunctionFlags.Async); - return isGenerator ? getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Return, returnType, isAsync) || errorType : - isAsync ? getAwaitedTypeNoAlias(returnType) || errorType : - returnType; + if (isGenerator) { + const returnIterationType = getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Return, returnType, isAsync); + if (!returnIterationType) { + return errorType; + } + return isAsync ? getAwaitedTypeNoAlias(unwrapAwaitedType(returnIterationType)) : returnIterationType; + } + return isAsync ? getAwaitedTypeNoAlias(returnType) || errorType : returnType; } function isUnwrappedReturnTypeVoidOrAny(func: SignatureDeclaration, returnType: Type): boolean { diff --git a/tests/baselines/reference/asyncGeneratorGenericNonWrappedReturn.symbols b/tests/baselines/reference/asyncGeneratorGenericNonWrappedReturn.symbols new file mode 100644 index 00000000000..611c7587c69 --- /dev/null +++ b/tests/baselines/reference/asyncGeneratorGenericNonWrappedReturn.symbols @@ -0,0 +1,17 @@ +=== tests/cases/conformance/generators/asyncGeneratorGenericNonWrappedReturn.ts === +// #48966 + +export async function* test(a: T): AsyncGenerator { +>test : Symbol(test, Decl(asyncGeneratorGenericNonWrappedReturn.ts, 0, 0)) +>T : Symbol(T, Decl(asyncGeneratorGenericNonWrappedReturn.ts, 2, 28)) +>a : Symbol(a, Decl(asyncGeneratorGenericNonWrappedReturn.ts, 2, 31)) +>T : Symbol(T, Decl(asyncGeneratorGenericNonWrappedReturn.ts, 2, 28)) +>AsyncGenerator : Symbol(AsyncGenerator, Decl(lib.es2018.asyncgenerator.d.ts, --, --)) +>T : Symbol(T, Decl(asyncGeneratorGenericNonWrappedReturn.ts, 2, 28)) +>T : Symbol(T, Decl(asyncGeneratorGenericNonWrappedReturn.ts, 2, 28)) +>T : Symbol(T, Decl(asyncGeneratorGenericNonWrappedReturn.ts, 2, 28)) + + return a // `T` should be allowed here even though the generator's `returnType` is `Awaited` +>a : Symbol(a, Decl(asyncGeneratorGenericNonWrappedReturn.ts, 2, 31)) +} + diff --git a/tests/baselines/reference/asyncGeneratorGenericNonWrappedReturn.types b/tests/baselines/reference/asyncGeneratorGenericNonWrappedReturn.types new file mode 100644 index 00000000000..d10c4619a51 --- /dev/null +++ b/tests/baselines/reference/asyncGeneratorGenericNonWrappedReturn.types @@ -0,0 +1,11 @@ +=== tests/cases/conformance/generators/asyncGeneratorGenericNonWrappedReturn.ts === +// #48966 + +export async function* test(a: T): AsyncGenerator { +>test : (a: T) => AsyncGenerator +>a : T + + return a // `T` should be allowed here even though the generator's `returnType` is `Awaited` +>a : T +} + diff --git a/tests/cases/conformance/generators/asyncGeneratorGenericNonWrappedReturn.ts b/tests/cases/conformance/generators/asyncGeneratorGenericNonWrappedReturn.ts new file mode 100644 index 00000000000..94222ebffe0 --- /dev/null +++ b/tests/cases/conformance/generators/asyncGeneratorGenericNonWrappedReturn.ts @@ -0,0 +1,9 @@ +// @target: esnext +// @strict: true +// @noEmit: true + +// #48966 + +export async function* test(a: T): AsyncGenerator { + return a // `T` should be allowed here even though the generator's `returnType` is `Awaited` +}