How to Handle TypeScript Error?

如何处理 TypeScript 抛出的错误?

问题

JavaScript 有 try...catch 语法用于捕捉程序中的错误情境,在需要时使用 throw 语法来抛出“任何错误”,通常建议会抛出 JS 默认的错误对象🔗如下:

// 抛出 JS 错误对象
try {
throw new Error('错误信息');
} catch (error) {
console.error(error.message);
}
// 抛出字符串
try {
throw '错误信息';
} catch (error) {
console.error(error);
}

我们要如何在 TypeScript 中正确的识别错误的类型呢?由于「任何错误」都可以被抛出,所以 TypeScript 会将 catch 接收到的错误对象视为 unknow,这样会让我们在开发时无法正确的判断错误。

解方

解方一:接受错误为 Any

在 TypeScript 中,我们可以将 catch 接收到的错误对象视为 any 类型,这样就可以接受任何类型的错误对象。

try {
throw new Error('错误信息');
} catch (error: any) {
console.error(error.message);
}

问题是这么做和没用 TypeScript 一样 😅,无法得知错误信息的类型。

解方二:断言错误类型

由于我们事先知道整段代码中只要错误就会抛出 Error 对象,因此可以使用 as 关键字来断言捕捉到的错误必定是 Error 对象,这样的做法好一点,因为我们可以确保错误对象也有类型。

但却不是最佳解法,因为如果错误对象不是 Error 对象,程序就会抛出错误,我们还是可能在程序中抛出任何类型的错误,进而导致 Runtime Error!

try {
throw new Error('错误信息');
} catch (error) {
console.error((error as Error).message);
}
// 如果我乱丢 Error 以外的东西呢? Runtime Error!
try {
throw 'Hello World';
} catch (error) {
console.error((error as Error).message);
}

最佳解法三:动态类型检查

最佳解法是在 catch 区块中检查错误对象的类型,这样可以确保错误对象的类型是正确的,我们可以通过 JS 的 instanceof🔗 语法来检查某个值是否为其他 Class 的实例对象或构造函数 。

try {
throw new Error('错误信息');
} catch (error) {
if (error instanceof Error) {
// 只有在 error 是 JS Error 对象时才会执行
console.error(error.message);
}
}

总结

非必要不使用 Any、断言类型,动态检测类型并基于默认错误对象来处理错误是最佳的解法。我们甚至可以基于原生错误对象定制错误对象,这样可以让我们在开发时更容易的识别错误,不过这又是延伸的话题了,可以参考看看延伸阅读了解更多。

延伸阅读