You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 18:30:04