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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:37:15