@@ -3883,23 +3883,41 @@ 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
+ inReturnStatement := node.Kind == ast.KindReturnStatement
3910
+ if functionFlags&FunctionFlagsAsync != 0 {
3911
+ 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)
3912
+ }
3913
+ effectiveExpr := expr // The effective expression for diagnostics purposes.
3914
+ if expr != nil {
3915
+ effectiveExpr = c.getEffectiveCheckNode(expr)
3916
+ }
3917
+ errorNode := core.IfElse(inReturnStatement && !inConditionalExpression, node, effectiveExpr)
3918
+ c.checkTypeAssignableToAndOptionallyElaborate(unwrappedExprType, unwrappedReturnType, errorNode, effectiveExpr, nil, nil)
3919
+ }
3920
+
3903
3921
func (c *Checker) checkWithStatement(node *ast.Node) {
3904
3922
if !c.checkGrammarStatementInAmbientContext(node) {
3905
3923
if node.Flags&ast.NodeFlagsAwaitContext != 0 {
@@ -9789,13 +9807,7 @@ func (c *Checker) checkFunctionExpressionOrObjectLiteralMethodDeferred(node *ast
9789
9807
if returnType != nil {
9790
9808
returnOrPromisedType := c.unwrapReturnType(returnType, functionFlags)
9791
9809
if returnOrPromisedType != nil {
9792
- effectiveCheckNode := c.getEffectiveCheckNode(body)
9793
- if (functionFlags & FunctionFlagsAsyncGenerator) == FunctionFlagsAsync {
9794
- 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)
9795
- c.checkTypeAssignableToAndOptionallyElaborate(awaitedType, returnOrPromisedType, effectiveCheckNode, effectiveCheckNode, nil, nil)
9796
- } else {
9797
- c.checkTypeAssignableToAndOptionallyElaborate(exprType, returnOrPromisedType, effectiveCheckNode, effectiveCheckNode, nil, nil)
9798
- }
9810
+ c.checkReturnExpression(node, returnOrPromisedType, body, body, exprType, false)
9799
9811
}
9800
9812
}
9801
9813
}
0 commit comments