Last updated: Feb 27, 2024
Reading timeยท3 min
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 the execution of the
program.
// ๐๏ธ 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:
never
vs void
If we didn't explicitly type the function's return value, TypeScript would have
inferred it as void
.
// ๐๏ธ 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 don't 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.
never
are never going to return anything.You very rarely 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
.
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 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
.
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.
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.
// ๐๏ธ 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.
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
.
You can learn more about the related topics by checking out the following tutorials: