@@ -5704,20 +5704,41 @@ module ts {
5704
5704
}
5705
5705
5706
5706
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 {
5707
5716
let func = getContainingFunction(node);
5708
5717
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);
5719
5723
}
5720
5724
}
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
+
5721
5742
return undefined;
5722
5743
}
5723
5744
@@ -5887,6 +5908,8 @@ module ts {
5887
5908
case SyntaxKind.ArrowFunction:
5888
5909
case SyntaxKind.ReturnStatement:
5889
5910
return getContextualTypeForReturnExpression(node);
5911
+ case SyntaxKind.YieldExpression:
5912
+ return getContextualTypeForYieldOperand(<YieldExpression>parent);
5890
5913
case SyntaxKind.CallExpression:
5891
5914
case SyntaxKind.NewExpression:
5892
5915
return getContextualTypeForArgument(<CallExpression>parent, node);
@@ -7912,7 +7935,7 @@ module ts {
7912
7935
// Also, there is no point in doing an assignability check if the function
7913
7936
// has no explicit return type, because the return type is directly computed
7914
7937
// from the yield expressions.
7915
- if (func.asteriskToken && func.type) {
7938
+ if (func && func .asteriskToken && func.type) {
7916
7939
let signatureElementType = getElementTypeFromIterableIterator(getTypeFromTypeNode(func.type), /*errorNode*/ undefined) || unknownType;
7917
7940
let expressionType = checkExpressionCached(node.expression, /*contextualMapper*/ undefined);
7918
7941
if (node.asteriskToken) {
@@ -9533,7 +9556,6 @@ module ts {
9533
9556
}
9534
9557
9535
9558
function getElementTypeFromIterable(iterable: Type, errorNode: Node): Type {
9536
- Debug.assert(languageVersion >= ScriptTarget.ES6);
9537
9559
// We want to treat type as an iterable, and get the type it is an iterable of. The iterable
9538
9560
// must have the following structure (annotated with the names of the variables below):
9539
9561
//
0 commit comments