如何在TypeScript中检查实例是否实现指定接口
在TypeScript中检查实例是否实现接口的方法
在TypeScript里直接像PHP那样用instanceof检查接口是行不通的——因为TypeScript的接口是纯编译时的类型定义,编译成JavaScript后会被完全移除,运行时根本不存在这个接口类型。所以我们得通过检查实例是否具备接口规定的特征(比如特定的属性或方法)来间接判断。
针对你的场景,假设IMyException接口定义了getResponse()方法(就像你之前的MyException类那样),这里有两种常用的解决方案:
方案一:自定义类型守卫函数(推荐)
类型守卫能让TypeScript在编译时识别出实例的类型,同时在运行时完成检查逻辑,兼顾类型安全和运行时判断:
// 先定义你的接口 interface IMyException { getResponse(): any; } // 自定义类型守卫函数 function isIMyException(err: unknown): err is IMyException { // 检查err是对象、不为null,且拥有getResponse方法 return ( typeof err === 'object' && err !== null && typeof (err as IMyException).getResponse === 'function' ); } // 修改你的handle方法 public handle() { return (err: unknown, req: Request, res: Response, next: any) => { if (isIMyException(err)) { // 这里TypeScript会自动把err识别为IMyException类型,调用getResponse不会报错 const response = err.getResponse(); res.status(500).send(response); } else { res.status(500).send((err as Error).message || 'Unknown error'); } } }
这个方法的好处是:
- 运行时准确判断实例是否符合接口特征
- 编译时获得完整的类型提示,避免类型错误
- 类型守卫函数可以复用在其他需要检查的地方
方案二:直接在条件中检查特征
如果场景简单,也可以不用单独写类型守卫,直接在if条件里检查关键属性/方法:
public handle() { return (err: unknown, req: Request, res: Response, next: any) => { if (err && typeof (err as any).getResponse === 'function') { const response = (err as IMyException).getResponse(); res.status(500).send(response); } else { res.status(500).send((err as Error).message || 'Unknown error'); } } }
这种写法更简洁,但缺点是需要手动类型断言,TypeScript无法自动缩小类型,代码可读性稍差。
为什么不能用instanceof?
你可能会好奇为什么不能像PHP那样用instanceof IMyException——因为instanceof是检查实例的原型链是否包含某个构造函数的原型,而TypeScript接口编译后完全消失,运行时没有对应的构造函数,所以写err instanceof IMyException会直接报错。
内容的提问来源于stack exchange,提问作者Kiren S
相关产品推荐
相关产品推荐

