TypeScript 中的错误处理:从 try/catch 到可靠代码
TypeScript 为 JavaScript 增加了静态类型,但运行时错误仍然是开发过程中不可分割的一部分。不当的异常处理可能导致应用程序崩溃、数据泄露或用户界面行为异常。在本文中,我们将探讨如何利用内置机制和高级模式在 TypeScript 中有效处理错误。
TypeScript 中的基本 try/catch
try/catch 结构是错误处理的基础。与 JavaScript 不同,在 TypeScript 中我们可以为捕获的错误指定类型。然而,有一个重要的细微差别:默认情况下,catch 块中的错误类型是 unknown,而不是 Error。
try { const data = JSON.parse('invalid json'); console.log(data);} catch (error) { // error 的类型是 unknown if (error instanceof Error) { console.error('发生错误:', error.message); } else { console.error('未知错误:', error); }}为什么这一点很重要?在 JavaScript 中,你可以抛出任何内容:字符串、数字、对象。TypeScript 保护我们避免在未检查的情况下不安全地访问错误属性。建议在使用错误类型之前始终进行检查。
自定义错误类
为了更精确地处理,可以创建继承自内置 Error 的自定义错误类。这允许你区分不同的错误类型并传递附加信息。
class ValidationError extends Error { constructor( public field: string, message: string ) { super(message); this.name = 'ValidationError'; }}
class NetworkError extends Error { constructor( public statusCode: number, message: string ) { super(message); this.name = 'NetworkError'; }}
function processUserData(data: unknown): void { if (!data || typeof data !== 'object') { throw new ValidationError('data', '数据无效'); } if (!('email' in data)) { throw new ValidationError('email', '邮箱是必填项'); }}
try { processUserData({ name: 'Ivan' });} catch (error) { if (error instanceof ValidationError) { console.error(`字段 ${error.field} 的验证错误: ${error.message}`); } else if (error instanceof NetworkError) { console.error(`网络错误 ${error.statusCode}: ${error.message}`); } else { console.error('未知错误:', error); }}这种方法使代码具有自文档性并简化了调试过程。你始终知道错误发生的位置和原因。
带错误的函数类型:never 和可辨识联合类型
TypeScript 提供了强大的工具来处理类型层面的错误。使用 never 类型表示总是抛出异常的函数,使用可辨识联合类型来返回错误。
function throwError(message: string): never { throw new Error(message);}
// 用于结果的可辨识联合类型type Result<T> = | { success: true; data: T } | { success: false; error: string };
function fetchUser(id: number): Result<{ name: string }> { try { // 模拟请求 if (id <= 0) { return { success: false, error: '无效ID' }; } return { success: true, data: { name: 'Anna' } }; } catch (error) { return { success: false, error: '网络错误' }; }}
const result = fetchUser(1);if (result.success) { console.log('用户:', result.data.name);} else { console.error('错误:', result.error);}Result 模式允许你避免隐式异常,并使错误处理