It doesn't hurt, but there's not much point to doing that. The never
acts as a bottom type with no possible values, and is aggressively removed from unions by the compiler:
Because never
is a subtype of every type, it is always omitted from union types and it is ignored in function return type inference as long as there are other types being returned.
That means if you inspect your function with something like IntelliSense, it will show up as:
function fn(n: number): number
so future coders are unlikely to even notice the difference. And in practice, there is no difference, because it's very hard to guarantee that an exception cannot be thrown inside some function.
A safer but more annoying approach is to encode possible failure in your return type without relying on exceptions, such as:
function fn( n: number ) : number | undefined {
if ( n < 0 ) return undefined;
return n;
}
or even more verbose but very explicit about intent:
type Success<T> = { success: true, value: T };
type Error<E> = { success: false, error: E };
function fn(n: number): Success<number> | Error<string> {
if (n < 0) return { success: false, error: "badness" };
return { success: true, value: n };
}
It really depends on your use case.
Probably I'd just leave your original as-is and use JSDoc comments to hint about possible exceptions.
/** Returns n if n is non-negative, throws an exception otherwise */
function fn(n: number): number | never {
if (n < 0) throw ("badness");
return n;
}
If you are using an editor with IntelliSense, the hints will show up:

Hope that helps. Good luck!