How to Handle TypeScript Error?
Problem
JavaScript has try...catch
syntax for capturing errors in the program, and uses throw
to throw “any error.” It is usually recommended to throw the default JS error object as follows:
// Throw JS error objecttry { throw new Error('Error message');} catch (error) { console.error(error.message);}
// Throw a stringtry { throw 'Error message';} catch (error) { console.error(error);}
How can we correctly identify the type of error in TypeScript? Since “any error” can be thrown, TypeScript treats the error object received in catch
as unknown
, which makes it difficult for us to accurately determine the error during development.
Solution
Solution 1: Accept Error as Any
In TypeScript, we can treat the error object received in catch
as any
, which allows us to accept error objects of any type.
try { throw new Error('Error message');} catch (error: any) { console.error(error.message);}
The problem with this approach is that it is the same as not using TypeScript 😅, as we cannot know the type of error information.
Solution 2: Assert Error Type
Since we know that any error thrown in this code will be an Error
object, we can use the as
keyword to assert that the caught error must be an Error
object. This approach is better because we can ensure that the error object has a type.
However, it is not the best solution, because if the error object is not an Error
object, the program will throw an error. We can still throw any type of error in the program, leading to a Runtime Error!
try { throw new Error('Error message');} catch (error) { console.error((error as Error).message);}
// What if I throw something other than Error? Runtime Error!try { throw 'Hello World';} catch (error) { console.error((error as Error).message);}
Best Solution 3: Dynamic Type Checking
The best solution is to check the type of the error object in the catch
block, ensuring that the type of the error object is correct. We can use JS’s instanceof
syntax to check if a value is an instance of another class or constructor.
try { throw new Error('Error message');} catch (error) { if (error instanceof Error) { // This will only execute if error is a JS Error object console.error(error.message); }}
Summary
Avoid using Any
or type assertions unnecessarily. Dynamic type checking and handling errors based on the default error object is the best solution. We can even customize error objects based on native error objects, making it easier to identify errors during development. However, this is an extended topic, and you can refer to further reading to learn more.
Further Reading
- 使用 JavaScript try…catch 來控制程式中的錯誤
- The 5 commandments of clean error handling in TypeScript - Marvin Roger
- Handling errors like a pro in TypeScript - Kolby Sisk