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
、断言类型,动态检测类型并基于默认错误对象来处理错误是最佳的解法。我们甚至可以基于原生错误对象定制错误对象,这样可以让我们在开发时更容易的识别错误,不过这又是延伸的话题了,可以参考看看延伸阅读了解更多。
延伸阅读
- 使用 JavaScript try…catch 来控制程序中的错误
- TypeScript 中干净错误处理的 5 条法则 - Marvin Roger
- 在 TypeScript 中像专业人士一样处理错误 - Kolby Sisk