@@ -9854,17 +9854,25 @@ namespace ts {
98549854 return aggregatedTypes;
98559855 }
98569856
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+ */
98619864 function checkAllCodePathsInNonVoidFunctionReturnOrThrow(func: FunctionLikeDeclaration, returnType: Type): void {
98629865 if (!produceDiagnostics) {
98639866 return;
98649867 }
98659868
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) {
98689876 return;
98699877 }
98709878
@@ -9874,13 +9882,14 @@ namespace ts {
98749882 return;
98759883 }
98769884
9877- if (func.flags & NodeFlags.HasExplicitReturn) {
9885+ if (!returnType || func.flags & NodeFlags.HasExplicitReturn) {
98789886 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);
98809888 }
98819889 }
98829890 else {
98839891 // 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
98849893 error(func.type, Diagnostics.A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value);
98859894 }
98869895 }
@@ -9955,14 +9964,10 @@ namespace ts {
99559964 emitAwaiter = true;
99569965 }
99579966
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);
99669971 }
99679972
99689973 if (node.body) {
@@ -9985,13 +9990,13 @@ namespace ts {
99859990 // check assignability of the awaited type of the expression body against the promised type of
99869991 // its return type annotation.
99879992 const exprType = checkExpression(<Expression>node.body);
9988- if (returnType ) {
9993+ if (returnOrPromisedType ) {
99899994 if (isAsync) {
99909995 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);
99929997 }
99939998 else {
9994- checkTypeAssignableTo(exprType, returnType , node.body);
9999+ checkTypeAssignableTo(exprType, returnOrPromisedType , node.body);
999510000 }
999610001 }
999710002
@@ -12131,14 +12136,9 @@ namespace ts {
1213112136 }
1213212137
1213312138 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);
1214212142 }
1214312143
1214412144 if (produceDiagnostics && !node.type) {
0 commit comments