如何编写基于instanceof检查的静态类型守卫?
通用错误实例类型守卫实现方案
我想要一种通用的错误实例检查方式,避免每次都写重复的嵌套判断代码:
try { /* ... */ } catch (error) { if (!(error instanceof Error)) { throw error; } if (!(error instanceof CustomError)) { throw error; } // 在这里处理 CustomError }
下面是针对你遇到的问题的两种可行解决方案:
方案一:子类可继承的静态类型守卫
你之前尝试的静态方法思路是对的,但需要调整TypeScript的类型约束,让静态方法能正确关联类的实例类型:
class BaseError extends Error { // 约束this为类的构造函数,同时关联实例类型T static isError<T extends BaseError>(this: new (...args: any[]) => T, error: unknown): error is T { return error instanceof this; } } // 子类无需额外编写,自动继承isError方法 class CustomError extends BaseError {} // 使用示例 try { throw new CustomError("自定义错误"); } catch (err) { if (CustomError.isError(err)) { // 此时err的类型被正确收窄为CustomError console.log("处理自定义错误:", err.message); } }
这样所有继承BaseError的子类都能直接使用子类.isError()方法,自动获得正确的类型推断。
方案二:独立通用泛型函数
如果不想依赖父类继承,可以写一个独立的泛型函数,明确指定构造函数与实例类型的关联:
function isErrorInstance<T>(error: unknown, errorClass: new (...args: any[]) => T): error is T { return error instanceof errorClass; } // 使用示例 try { throw new CustomError("自定义错误"); } catch (err) { if (isErrorInstance(err, CustomError)) { // err类型被收窄为CustomError console.log("处理自定义错误:", err.message); } }
这个函数通过泛型T绑定实例类型,参数errorClass被约束为返回T实例的构造函数,TypeScript会自动根据传入的类推断出正确的实例类型。
为什么你之前的尝试失败?
- 静态方法的this类型问题:TypeScript不允许在静态方法的类型守卫中直接使用
this作为实例类型,因为静态上下文的this指向类的构造函数而非实例。通过显式约束this为构造函数类型并关联实例T,就能解决这个报错。 - 泛型函数的类型关联错误:你之前的泛型参数
ErrorClass extends typeof Error指向的是构造函数类型,而类型守卫error is ErrorClass错误地将error标注为构造函数类型,而非实例类型。调整泛型参数绑定实例类型,同时约束参数为构造函数,就能修复这个问题。
内容的提问来源于stack exchange,提问作者Biller Builder
相关产品推荐
相关产品推荐

