diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9cbbb3a28bd5f..677c6aac32c56 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -883,6 +883,7 @@ namespace ts { let globalBooleanType: ObjectType; let globalRegExpType: ObjectType; let globalThisType: GenericType; + let globalYieldType: GenericType; let anyArrayType: Type; let autoArrayType: Type; let anyReadonlyArrayType: Type; @@ -24931,6 +24932,16 @@ namespace ts { }); } + function getYieldTypeArgument(type: Type): Type | undefined { + return getObjectFlags(type) & ObjectFlags.Reference && (type as TypeReference).target === globalYieldType ? getTypeArguments(type as TypeReference)[0] : undefined; + } + + function getYieldTypeFromContextualType(type: Type): Type | undefined { + return mapType(type, t => { + return t.flags & TypeFlags.Intersection ? forEach((t as IntersectionType).types, getYieldTypeArgument) : getYieldTypeArgument(t); + }); + } + function getContextualThisParameterType(func: SignatureDeclaration): Type | undefined { if (func.kind === SyntaxKind.ArrowFunction) { return undefined; @@ -32326,6 +32337,11 @@ namespace ts { return getIterationTypeOfIterable(use, IterationTypeKind.Return, yieldExpressionType, node.expression) || anyType; } + + const suggestedReturnType = yieldedType && getYieldTypeFromContextualType(yieldedType); + if (suggestedReturnType) { + return suggestedReturnType; + } else if (returnType) { return getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Next, returnType, isAsync) || anyType; @@ -40618,6 +40634,7 @@ namespace ts { globalReadonlyArrayType = getGlobalTypeOrUndefined("ReadonlyArray" as __String, /*arity*/ 1) as GenericType || globalArrayType; anyReadonlyArrayType = globalReadonlyArrayType ? createTypeFromGenericGlobalType(globalReadonlyArrayType, [anyType]) : anyArrayType; globalThisType = getGlobalTypeOrUndefined("ThisType" as __String, /*arity*/ 1) as GenericType; + globalYieldType = getGlobalTypeOrUndefined("YieldType" as __String, /*arity*/ 1) as GenericType; if (augmentations) { // merge _nonglobal_ module augmentations. diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index 461d98977730d..d1d24bab20a1f 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -1545,6 +1545,11 @@ type Uncapitalize = intrinsic; */ interface ThisType { } +/** + * Marker for yield expressions return types + */ +interface YieldType { } + /** * Represents a raw buffer of binary data, which is used to store data for the * different typed arrays. ArrayBuffers cannot be read from or written to directly,