Function lacks ending return statement Error in TS

avatar
Borislav Hadzhiev

Last updated: Feb 27, 2024
4 min

banner

# Function lacks ending return statement Error in TS

The "Function lacks ending return statement and return type does not include undefined" error occurs when not all code paths of a function with an explicit return type return a value.

To solve the error, return a value from all code paths or include undefined in the function's return type.

# Forgetting to return a value from a function

Here is an example of how the error occurs.

index.ts
// โ›” Error:๏ธ Function lacks ending return statement // and return type does not include 'undefined'.ts(2366) const getNumber = (): number => { if (Math.random() > 0.5) { return 100; } // ๐Ÿ‘‡๏ธ No return value here ๐Ÿ‘‡๏ธ };

function lacks ending return statement

We've explicitly set the function's return type to number but not all code paths return a value.

# Make sure to return a value from all code paths

To solve the error, make sure to return a value from all of the function's code paths.

index.ts
// โœ… Works now const getNumber = (): number => { if (Math.random() > 0.5) { return 100; } return 50; // ๐Ÿ‘ˆ๏ธ all code paths return a value };

make sure to return value from all code paths

The code for this article is available on GitHub

Even if the if condition isn't met, a value of the correct type is returned.

# Forgetting to return a value from your catch() block

The error also occurs when using a try/catch statement in a function for which we've set a return type.

index.ts
// โ›” Error:๏ธ Function lacks ending return statement // and return type does not include 'undefined'.ts(2366) const getPromise = async (): Promise<number> => { try { const result = await Promise.resolve(42); return result; } catch (err) { console.log(err); // ๐Ÿ‘‡๏ธ no return value here ๐Ÿ‘‡๏ธ } };

The issue is that we've typed the function to return Promise<number>, so TypeScript expects all calls to the function to return Promise<number>, even the ones that error out.

# Use a union type to solve the error

Use a union type to set the function's return type to Promise<number | undefined>.

index.ts
// โœ… Works now const getPromise = async (): Promise<number | undefined> => { try { const result = await Promise.resolve(42); return result; } catch (err) { console.log(err); return; } };

use union type to solve the error

The code for this article is available on GitHub

Now TypeScript knows that the function returns a Promise of type number or undefined, which is an accurate representation of the function's return type.

When you get the return value of the function, use a type guard to determine if it's a number or undefined.

index.ts
const getPromise = async (): Promise<number | undefined> => { try { const result = await Promise.resolve(42); return result; } catch (err) { console.log(err); return; } }; getPromise().then((value) => { if (typeof value === 'number') { // โœ… We know that value is number console.log(value.toFixed()); } });

use type guard to determine return value type

A simple if statement in which we used the typeof operator serves as a type guard.

TypeScript knows that the value is a number in the if block, so we can safely access number-related built-in methods.

# Sometimes TypeScript isn't able to accurately determine the flow

The third example shows how TypeScript is not always able to accurately determine the flow of a function.

index.ts
// โ›” Error:๏ธ Function lacks ending return statement // and return type does not include 'undefined'.ts(2366) const getString = (): string => { if ('hello'.length === 5) { return 'hello'; } else if ('hello'.length === 6) { return 'hello'; } // ๐Ÿ‘‡๏ธ TypeScript doesn't know that ๐Ÿ‘‡๏ธ // getting here is impossible };

The string hello has a length of 5, so we know that the if block will run and we will always return the value hello, but TypeScript doesn't know.

# Replace the ending else if statement with an else statement

To solve this, we have to replace the ending else if statement with an else or simply remove the condition.

The following 2 examples are the same.

index.ts
// โœ… Works now const getString = (): string => { if ('hello'.length === 5) { return 'hello'; } else { return 'bye'; } };
The code for this article is available on GitHub

Or remove the else block completely.

index.ts
// โœ… Works now const getString = (): string => { if ('hello'.length === 5) { return 'hello'; } return 'bye'; };

Either way, TypeScript is now able to determine that all of the function's code paths return a value of type string.

# Returning values only from nested functions

A common cause of the error is when we return a value from an inner function or a callback and think that the value also gets returned from the outer function.

index.ts
// โ›” Error:๏ธ Function lacks ending return statement // and return type does not include 'undefined'.ts(2366) const getString = (): string => { if ('hello'.length === 5) { return 'hello'; } function inner() { return 'bye'; } inner(); };

The inner function returns a string, however, returning a value from a nested function doesn't mean the value gets returned from the outer function.

If you are in a similar situation, make sure to return the result of calling the inner function.

index.ts
// โœ… Works now const getString = (): string => { if ('hello'.length === 5) { return 'hello'; } function inner() { return 'bye'; } return inner(); };
The code for this article is available on GitHub

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.

Copyright ยฉ 2024 Borislav Hadzhiev