@@ -9854,17 +9854,25 @@ namespace ts {
9854
9854
return aggregatedTypes;
9855
9855
}
9856
9856
9857
- // TypeScript Specification 1.0 (6.3) - July 2014
9858
- // An explicitly typed function whose return type isn't the Void or the Any type
9859
- // must have at least one return statement somewhere in its body.
9860
- // An exception to this rule is if the function implementation consists of a single 'throw' statement.
9857
+ /*
9858
+ *TypeScript Specification 1.0 (6.3) - July 2014
9859
+ * An explicitly typed function whose return type isn't the Void or the Any type
9860
+ * must have at least one return statement somewhere in its body.
9861
+ * An exception to this rule is if the function implementation consists of a single 'throw' statement.
9862
+ * @param returnType - return type of the function, can be undefined if return type is not explicitly specified
9863
+ */
9861
9864
function checkAllCodePathsInNonVoidFunctionReturnOrThrow(func: FunctionLikeDeclaration, returnType: Type): void {
9862
9865
if (!produceDiagnostics) {
9863
9866
return;
9864
9867
}
9865
9868
9866
- // Functions that return 'void' or 'any' don't need any return expressions.
9867
- if (returnType === voidType || isTypeAny(returnType)) {
9869
+ // Functions with with an explicitly specified 'void' or 'any' return type don't need any return expressions.
9870
+ if (returnType && (returnType === voidType || isTypeAny(returnType))) {
9871
+ return;
9872
+ }
9873
+
9874
+ // if return type is not specified then we'll do the check only if 'noImplicitReturns' option is set
9875
+ if (!returnType && !compilerOptions.noImplicitReturns) {
9868
9876
return;
9869
9877
}
9870
9878
@@ -9874,13 +9882,14 @@ namespace ts {
9874
9882
return;
9875
9883
}
9876
9884
9877
- if (func.flags & NodeFlags.HasExplicitReturn) {
9885
+ if (!returnType || func.flags & NodeFlags.HasExplicitReturn) {
9878
9886
if (compilerOptions.noImplicitReturns) {
9879
- error(func.type, Diagnostics.Not_all_code_paths_return_a_value);
9887
+ error(func.type || func , Diagnostics.Not_all_code_paths_return_a_value);
9880
9888
}
9881
9889
}
9882
9890
else {
9883
9891
// This function does not conform to the specification.
9892
+ // NOTE: having returnType !== undefined is a precondition for entering this branch so func.type will always be present
9884
9893
error(func.type, Diagnostics.A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value);
9885
9894
}
9886
9895
}
@@ -9955,14 +9964,10 @@ namespace ts {
9955
9964
emitAwaiter = true;
9956
9965
}
9957
9966
9958
- const returnType = node.type && getTypeFromTypeNode(node.type);
9959
- let promisedType: Type;
9960
- if (returnType && isAsync) {
9961
- promisedType = checkAsyncFunctionReturnType(node);
9962
- }
9963
-
9964
- if (returnType && !node.asteriskToken) {
9965
- checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, isAsync ? promisedType : returnType);
9967
+ const returnOrPromisedType = node.type && (isAsync ? checkAsyncFunctionReturnType(node) : getTypeFromTypeNode(node.type));
9968
+ if (!node.asteriskToken) {
9969
+ // return is not necessary in the body of generators
9970
+ checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnOrPromisedType);
9966
9971
}
9967
9972
9968
9973
if (node.body) {
@@ -9985,13 +9990,13 @@ namespace ts {
9985
9990
// check assignability of the awaited type of the expression body against the promised type of
9986
9991
// its return type annotation.
9987
9992
const exprType = checkExpression(<Expression>node.body);
9988
- if (returnType ) {
9993
+ if (returnOrPromisedType ) {
9989
9994
if (isAsync) {
9990
9995
const awaitedType = checkAwaitedType(exprType, node.body, Diagnostics.Expression_body_for_async_arrow_function_does_not_have_a_valid_callable_then_member);
9991
- checkTypeAssignableTo(awaitedType, promisedType , node.body);
9996
+ checkTypeAssignableTo(awaitedType, returnOrPromisedType , node.body);
9992
9997
}
9993
9998
else {
9994
- checkTypeAssignableTo(exprType, returnType , node.body);
9999
+ checkTypeAssignableTo(exprType, returnOrPromisedType , node.body);
9995
10000
}
9996
10001
}
9997
10002
@@ -12131,14 +12136,9 @@ namespace ts {
12131
12136
}
12132
12137
12133
12138
checkSourceElement(node.body);
12134
- if (node.type && !isAccessor(node.kind) && !node.asteriskToken) {
12135
- const returnType = getTypeFromTypeNode(node.type);
12136
- let promisedType: Type;
12137
- if (isAsync) {
12138
- promisedType = checkAsyncFunctionReturnType(node);
12139
- }
12140
-
12141
- checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, isAsync ? promisedType : returnType);
12139
+ if (!isAccessor(node.kind) && !node.asteriskToken) {
12140
+ const returnOrPromisedType = node.type && (isAsync ? checkAsyncFunctionReturnType(node) : getTypeFromTypeNode(node.type));
12141
+ checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnOrPromisedType);
12142
12142
}
12143
12143
12144
12144
if (produceDiagnostics && !node.type) {
0 commit comments