如何在TypeScript中处理NodeJS的SystemError等错误类型?
在TypeScript中缩小Node.js异常类型的方案
针对你遇到的Node.js未导出SystemError类型、无法直接缩小错误类型的问题,有以下几种可行方案:
1. 自定义类型守卫(Type Predicate)
利用TypeScript的类型谓词,通过检查错误对象的特征属性来识别SystemError。需要确保项目安装了最新版的@types/node(执行npm install @types/node --save-dev更新),其中包含NodeJS.SystemError类型定义。
import { createClient } from 'redis'; const redisClient = createClient(); // 自定义类型守卫,判断是否为NodeJS.SystemError function isSystemError(err: unknown): err is NodeJS.SystemError { return ( typeof err === 'object' && err !== null && 'code' in err && typeof (err as NodeJS.SystemError).code === 'string' && 'errno' in err && typeof (err as NodeJS.SystemError).errno === 'number' && 'syscall' in err && typeof (err as NodeJS.SystemError).syscall === 'string' ); } redisClient.on('error', (err) => { if (isSystemError(err)) { if (err.code === 'ECONNREFUSED') { throw new Error('连接被拒绝'); } // 此处err的类型已被缩小为NodeJS.SystemError,可访问其专属属性 console.log(`系统错误:${err.code},系统调用:${err.syscall}`); } throw err; });
2. 直接通过属性检查实现类型推断
如果不想自定义类型守卫,也可以通过条件判断直接让TypeScript自动推断错误类型,适合简单场景:
redisClient.on('error', (err) => { // 检查err是否为包含code属性的Error对象 if (err instanceof Error && 'code' in err && typeof err.code === 'string') { if (err.code === 'ECONNREFUSED') { throw new Error('连接被拒绝'); } // 此处TypeScript会自动推断err包含code属性 console.log(`错误码:${err.code}`); } throw err; });
3. 自行定义SystemError类型
如果@types/node中的NodeJS.SystemError无法使用,可以手动定义符合Node.js系统错误特征的类型:
import { createClient } from 'redis'; const redisClient = createClient(); // 自定义SystemError类型 interface SystemError extends Error { code: string; errno: number; syscall: string; address?: string; port?: number; } // 对应的类型守卫 function isSystemError(err: unknown): err is SystemError { return ( err instanceof Error && 'code' in err && typeof (err as SystemError).code === 'string' && 'errno' in err && typeof (err as SystemError).errno === 'number' && 'syscall' in err && typeof (err as SystemError).syscall === 'string' ); } redisClient.on('error', (err) => { if (isSystemError(err)) { if (err.code === 'ECONNREFUSED') { throw new Error('连接被拒绝'); } } throw err; });
内容的提问来源于stack exchange,提问作者Ron Zano
相关产品推荐
相关产品推荐

