@@ -5704,20 +5704,41 @@ module ts {
57045704 }
57055705
57065706 function getContextualTypeForReturnExpression(node: Expression): Type {
5707+ let func = getContainingFunction(node);
5708+ if (func && !func.asteriskToken) {
5709+ return getContextualReturnType(func);
5710+ }
5711+
5712+ return undefined;
5713+ }
5714+
5715+ function getContextualTypeForYieldOperand(node: YieldExpression): Type {
57075716 let func = getContainingFunction(node);
57085717 if (func) {
5709- // If the containing function has a return type annotation, is a constructor, or is a get accessor whose
5710- // corresponding set accessor has a type annotation, return statements in the function are contextually typed
5711- if (func.type || func.kind === SyntaxKind.Constructor || func.kind === SyntaxKind.GetAccessor && getSetAccessorTypeAnnotationNode(<AccessorDeclaration>getDeclarationOfKind(func.symbol, SyntaxKind.SetAccessor))) {
5712- return getReturnTypeOfSignature(getSignatureFromDeclaration(func));
5713- }
5714- // Otherwise, if the containing function is contextually typed by a function type with exactly one call signature
5715- // and that call signature is non-generic, return statements are contextually typed by the return type of the signature
5716- let signature = getContextualSignatureForFunctionLikeDeclaration(<FunctionExpression>func);
5717- if (signature) {
5718- return getReturnTypeOfSignature(signature);
5718+ let contextualReturnType = getContextualReturnType(func);
5719+ if (contextualReturnType) {
5720+ return node.asteriskToken
5721+ ? contextualReturnType
5722+ : getElementTypeFromIterableIterator(contextualReturnType, /*errorNode*/ undefined);
57195723 }
57205724 }
5725+
5726+ return undefined;
5727+ }
5728+
5729+ function getContextualReturnType(functionDecl: FunctionLikeDeclaration): Type {
5730+ // If the containing function has a return type annotation, is a constructor, or is a get accessor whose
5731+ // corresponding set accessor has a type annotation, return statements in the function are contextually typed
5732+ if (functionDecl.type || functionDecl.kind === SyntaxKind.Constructor || functionDecl.kind === SyntaxKind.GetAccessor && getSetAccessorTypeAnnotationNode(<AccessorDeclaration>getDeclarationOfKind(functionDecl.symbol, SyntaxKind.SetAccessor))) {
5733+ return getReturnTypeOfSignature(getSignatureFromDeclaration(functionDecl));
5734+ }
5735+ // Otherwise, if the containing function is contextually typed by a function type with exactly one call signature
5736+ // and that call signature is non-generic, return statements are contextually typed by the return type of the signature
5737+ let signature = getContextualSignatureForFunctionLikeDeclaration(<FunctionExpression>functionDecl);
5738+ if (signature) {
5739+ return getReturnTypeOfSignature(signature);
5740+ }
5741+
57215742 return undefined;
57225743 }
57235744
@@ -5887,6 +5908,8 @@ module ts {
58875908 case SyntaxKind.ArrowFunction:
58885909 case SyntaxKind.ReturnStatement:
58895910 return getContextualTypeForReturnExpression(node);
5911+ case SyntaxKind.YieldExpression:
5912+ return getContextualTypeForYieldOperand(<YieldExpression>parent);
58905913 case SyntaxKind.CallExpression:
58915914 case SyntaxKind.NewExpression:
58925915 return getContextualTypeForArgument(<CallExpression>parent, node);
@@ -7912,7 +7935,7 @@ module ts {
79127935 // Also, there is no point in doing an assignability check if the function
79137936 // has no explicit return type, because the return type is directly computed
79147937 // from the yield expressions.
7915- if (func.asteriskToken && func.type) {
7938+ if (func && func .asteriskToken && func.type) {
79167939 let signatureElementType = getElementTypeFromIterableIterator(getTypeFromTypeNode(func.type), /*errorNode*/ undefined) || unknownType;
79177940 let expressionType = checkExpressionCached(node.expression, /*contextualMapper*/ undefined);
79187941 if (node.asteriskToken) {
@@ -9533,7 +9556,6 @@ module ts {
95339556 }
95349557
95359558 function getElementTypeFromIterable(iterable: Type, errorNode: Node): Type {
9536- Debug.assert(languageVersion >= ScriptTarget.ES6);
95379559 // We want to treat type as an iterable, and get the type it is an iterable of. The iterable
95389560 // must have the following structure (annotated with the names of the variables below):
95399561 //
0 commit comments