TypeScript 错误处理:try/catch、自定义类与严格类型化

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程
```html

引言:为什么 TypeScript 中的错误处理不仅仅是 try/catch

TypeScript 为 JavaScript 增加了静态类型检查,但运行时错误(runtime errors)仍然是任何应用程序的一部分。与纯 JS 不同,在纯 JS 中 catch(e) 返回 any,而 TypeScript 提供了更严格的机制。正确的错误处理不仅是为了防止崩溃,更是为了创建一个易于调试和维护代码的清晰系统。在本文中,我们将分析所有方面:从基本的 try/catch 到创建具有完整类型化的自定义错误层次结构。



1. try/catch 的基本语法和 unknown 类型的问题

经典结构

TypeScript 中的基本结构与 JavaScript 相同:

try {    // 可能抛出异常的代码    const data = JSON.parse('{"name": "TypeScript"}');    console.log(data.name);} catch (error) {    // 错误处理    console.error('发生错误:', error);}

但有一个重要区别:在 TypeScript 中,catch 块中的变量 error 的类型是 unknown(而不是 JavaScript 中未指定时的 any)。这是为了类型安全。



unknown 的问题及其解决方法

unknown 类型意味着我们不能直接访问错误的属性,例如 error.message。编译器会报错:

catch (error) {    // 错误 TS2571: Object is of type 'unknown'.    console.log(error.message); // ❌ 无法编译}

要访问属性,需要收窄类型:

catch (error) {    if (error instanceof Error) {        console.log(error.message); // ✅ 正常工作    } else {        console.log('未知错误:', error);    }}

或者使用属性存在性检查:

catch (error) {    if (error && typeof error === 'object' && 'message' in error) {        console.log((error as { message: string }).message);    }}


2. 创建带类型化的自定义错误类

为什么这很重要?

标准的 Error 只包含 name、message 和 stack。在实际项目中,通常需要额外的字段:错误代码、HTTP 状态码、用于日志记录的数据。TypeScript 允许创建具有完整类型支持的错误类层次结构。



自定义类示例

// 所有应用程序错误的基础类class AppError extends Error {    public readonly statusCode: number;    public readonly isOperational: boolean;

constructor(message: string, statusCode: number = 500, isOperational: boolean = true) { super(message); this.name = 'AppError'; this.statusCode = statusCode; this.isOperational = isOperational; // 恢复原型(TypeScript 需要) Object.setPrototypeOf(this, new.target.prototype); }}

// 专门化的错误class NotFoundError extends AppError { constructor(resource: string) { super(`${resource} 未找到`, 404); this.name = 'NotFoundError'; }}

class ValidationError extends AppError { public readonly errors: string[];

constructor(errors: string[]) { super('验证错误', 400); this.name = 'ValidationError'; this.errors = errors; }}


与 try/catch 一起使用

function getUser(id: number): User {    if (id <= 0) {        throw new ValidationError(['ID 必须为正数']);    }    // ... 获取用户的逻辑    if (!user) {        throw new NotFoundError('用户');    }    return user;}

try { const user = getUser(-1);} catch (error) { if (err ```

博客

书籍推荐