Declare a function that throws an Error in TypeScript

avatar

Borislav Hadzhiev

Last updated: Mar 4, 2022

banner

Photo from Unsplash

Declare a function that throws an Error in TypeScript #

To declare a function that throws an error, set its return type to never. The never type is used for functions that never return a value, in other words functions that throw an exception or terminate execution of the program.

index.ts
// 👇️ function throwErr(): never function throwErr(): never { throw new Error('Something went wrong'); }

The never type is used very rarely in TypeScript.

It is used when the function is never going to reach a return statement, which happens mostly for 2 reasons:

  1. The function throws an error
  2. The function loops infinitely

If we didn't explicitly type the function's return value, TypeScript would have inferred it as void.

index.ts
// 👇️ function throwErr(): void function throwErr() { throw new Error('Something went wrong'); }

The difference between never and void is that void is used for functions that do not return anything (or return undefined).

If we accidentally return a value from a function that has a return type of void, we would get an error.

Whereas, functions that have a return type of never are never going to return anything.

It's very rare that you have to set a function's return type to never. For example, if the function throws an error only some of the time, you shouldn't set its return type to never.

index.ts
function sometimesThrow(): number { if (Math.random() > 0.5) { return 100; } throw new Error('Something went wrong'); } // 👇️ const result: number const result = sometimesThrow(); console.log(result.toFixed());

The function in the example above returns a number some of the time, and throws an error on some invocations.

You could use a union type to set its value to number or never.

index.ts
function sometimesThrow(): number | never { if (Math.random() > 0.5) { return 100; } throw new Error('Something went wrong'); } // 👇️ const result: number const result = sometimesThrow(); console.log(result.toFixed());

But this is only useful to inform your colleagues that the function might throw an error.

Notice that the result variable is still typed as a number even though we set the function's return type to number | never.

This is because every other type absorbs never in a union type.

index.ts
// 👇️ type T = number type T = number | never;

Notice that number | never is simplified to number. This is the case when using never with any other type in a union.

You could be explicit and set the function's return type to number | never, because that would indicate to your colleagues that the function might throw an unhandled error and they might have to wrap the invocation in a try/catch statement.

However, this doesn't technically influence the function's return type.

It should also be noted that there isn't a way for you to distinguish the type of error a function throws.

For example, if you have a class CustomError that extends from Error, there's no way for you to tell TypeScript that your function throws a CustomError instead of an Error.

If you set the function's return type to CustomError, this means that the function will return (and not throw) a value typed as CustomError.

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.