TypeScript中自定义Error子类instanceof及constructor.name显示父类名问题
解决TypeScript继承Error类的instanceof识别问题
问题根源
你遇到的问题有两个核心原因:
- Error类的特殊性:JavaScript的Error构造函数在实例化时会自行重置原型链,导致子类实例的
constructor指向被覆盖为Error,进而让instanceof判断失效。 - catch分支顺序错误:因为
ExpressError是Error的子类,e instanceof Error会先匹配所有Error子类实例,导致后续的ExpressError分支永远不会执行。
修复步骤
1. 修正ExpressError类的实现
修改构造函数并手动修复原型链:
export default class ExpressError extends Error { status: number; error_id: number; no_db_store: boolean; name = "ExpressError"; constructor(message: string, status: number, error_id = 0, no_db_store = true) { // 必须传递message给super,确保Error内部属性正确初始化 super(message); this.status = status; this.error_id = error_id; this.no_db_store = no_db_store; // 修复原型链,让实例的constructor指向当前类 Object.setPrototypeOf(this, ExpressError.prototype); } }
- 移除重复的
message声明:父类Error已包含该属性,无需重复定义。 - 调用
super(message):替代空的super(),确保Error类完成内部状态初始化。 - 添加
Object.setPrototypeOf:这是修复Error子类原型链的关键,抵消Error构造函数对原型链的重置操作,让instanceof和constructor.name恢复正常。
2. 调整catch块的分支顺序
将ExpressError的判断放在通用Error判断之前,因为子类实例会同时满足父类的instanceof条件:
catch (e: unknown) { let structured_error: { [key: string]: string | undefined | number | boolean } = {}; // 检查是否为Sequelize错误 if (e instanceof UniqueConstraintError) { structured_error = { message: e.errors[0].message, status: 403, stack: e.stack, }; } // 优先判断子类ExpressError else if (e instanceof ExpressError) { structured_error = { message: e.message, stack: e.stack, status: e.status, no_db_store: e.no_db_store }; } // 最后处理通用Error实例 else if (e instanceof Error) { structured_error = { message: e.message, stack: e.stack, }; } }
验证效果
修正后:
e.constructor.name会正确输出ExpressError。- catch块会优先匹配
ExpressError分支,再处理普通Error实例。
内容的提问来源于stack exchange,提问作者Hossam Hamza
相关产品推荐
相关产品推荐

