@@ -3883,23 +3883,42 @@ func (c *Checker) checkReturnStatement(node *ast.Node) {
3883
3883
}
3884
3884
} else if c.getReturnTypeFromAnnotation(container) != nil {
3885
3885
unwrappedReturnType := core.OrElse(c.unwrapReturnType(returnType, functionFlags), returnType)
3886
- unwrappedExprType := exprType
3887
- if functionFlags&FunctionFlagsAsync != 0 {
3888
- unwrappedExprType = c.checkAwaitedType(exprType, false /*withAlias*/, node, diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member)
3889
- }
3890
- if unwrappedReturnType != nil {
3891
- // If the function has a return type, but promisedType is
3892
- // undefined, an error will be reported in checkAsyncFunctionReturnType
3893
- // so we don't need to report one here.
3894
- c.checkTypeAssignableToAndOptionallyElaborate(unwrappedExprType, unwrappedReturnType, node, exprNode, nil, nil)
3895
- }
3886
+ c.checkReturnExpression(container, unwrappedReturnType, node, node.Expression(), exprType, false)
3896
3887
}
3897
3888
} else if !ast.IsConstructorDeclaration(container) && c.compilerOptions.NoImplicitReturns.IsTrue() && !c.isUnwrappedReturnTypeUndefinedVoidOrAny(container, returnType) {
3898
3889
// The function has a return type, but the return statement doesn't have an expression.
3899
3890
c.error(node, diagnostics.Not_all_code_paths_return_a_value)
3900
3891
}
3901
3892
}
3902
3893
3894
+ // When checking an arrow expression such as `(x) => exp`, then `node` is the expression `exp`.
3895
+ // Otherwise, `node` is a return statement.
3896
+ func (c *Checker) checkReturnExpression(container *ast.Node, unwrappedReturnType *Type, node *ast.Node, expr *ast.Node, exprType *Type, inConditionalExpression bool) {
3897
+ unwrappedExprType := exprType
3898
+ functionFlags := getFunctionFlags(container)
3899
+ if expr != nil {
3900
+ unwrappedExpr := ast.SkipParentheses(expr)
3901
+ if ast.IsConditionalExpression(unwrappedExpr) {
3902
+ whenTrue := unwrappedExpr.AsConditionalExpression().WhenTrue
3903
+ whenFalse := unwrappedExpr.AsConditionalExpression().WhenFalse
3904
+ c.checkReturnExpression(container, unwrappedReturnType, node, whenTrue, c.checkExpression(whenTrue), true /*inConditionalExpression*/)
3905
+ c.checkReturnExpression(container, unwrappedReturnType, node, whenFalse, c.checkExpression(whenFalse), true /*inConditionalExpression*/)
3906
+ return
3907
+ }
3908
+ }
3909
+
3910
+ inReturnStatement := node.Kind == ast.KindReturnStatement
3911
+ if functionFlags&FunctionFlagsAsync != 0 {
3912
+ unwrappedExprType = c.checkAwaitedType(exprType, false /*withAlias*/, node, diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member)
3913
+ }
3914
+ effectiveExpr := expr // The effective expression for diagnostics purposes.
3915
+ if expr != nil {
3916
+ effectiveExpr = c.getEffectiveCheckNode(expr)
3917
+ }
3918
+ errorNode := core.IfElse(inReturnStatement && !inConditionalExpression, node, effectiveExpr)
3919
+ c.checkTypeAssignableToAndOptionallyElaborate(unwrappedExprType, unwrappedReturnType, errorNode, effectiveExpr, nil, nil)
3920
+ }
3921
+
3903
3922
func (c *Checker) checkWithStatement(node *ast.Node) {
3904
3923
if !c.checkGrammarStatementInAmbientContext(node) {
3905
3924
if node.Flags&ast.NodeFlagsAwaitContext != 0 {
@@ -9775,13 +9794,7 @@ func (c *Checker) checkFunctionExpressionOrObjectLiteralMethodDeferred(node *ast
9775
9794
if returnType != nil {
9776
9795
returnOrPromisedType := c.unwrapReturnType(returnType, functionFlags)
9777
9796
if returnOrPromisedType != nil {
9778
- effectiveCheckNode := c.getEffectiveCheckNode(body)
9779
- if (functionFlags & FunctionFlagsAsyncGenerator) == FunctionFlagsAsync {
9780
- awaitedType := c.checkAwaitedType(exprType, false /*withAlias*/, effectiveCheckNode, diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member)
9781
- c.checkTypeAssignableToAndOptionallyElaborate(awaitedType, returnOrPromisedType, effectiveCheckNode, effectiveCheckNode, nil, nil)
9782
- } else {
9783
- c.checkTypeAssignableToAndOptionallyElaborate(exprType, returnOrPromisedType, effectiveCheckNode, effectiveCheckNode, nil, nil)
9784
- }
9797
+ c.checkReturnExpression(node, returnOrPromisedType, body, body, exprType, false);
9785
9798
}
9786
9799
}
9787
9800
}
0 commit comments