I understand that the reason why typesafe error handling is not a thing in ts is because we are missing the throws clause from functions. So because of this whenever I do this:
function mighThrow(input: number): void {
if (input === 1) {
throw new TypeError('cannot be one')
} else if(input === 2) {
throw new SyntaxError('invalid syntax: 2')
}
console.log('all good', input)
}
I can't catch the errors with accurate typing:
try {
mighThrow(1)
} catch(e) {
// e is any, even though it could be TypeError | SyntaxError
}
The issue is the same with Promises, the catcher functions argument is hardcoded any:
interface Promise<T> {
then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<TResult1 | TResult2>;
catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null): Promise<T | TResult>;
}
The argument of catch is any.
So my question is how can I get around this? If I'm a library author, is there a typesafe way to help users figure out what exactly are they catching? I'm aware of solutions like adding an Either type and calling it a day, but this enforces handling the error on the spot, which just turns the code into something similar to as if the language would have checked exceptions.