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

TypeScript中Stub类为何需实现私有成员?如何解决?

TypeScript Stub类时私有成员报错的原因与解决方法

为什么会要求实现私有成员?

TypeScript的结构类型系统在检查对象字面量与类类型的匹配度时,会校验类的所有成员——不管是公共还是私有。虽然私有成员在外部代码里无法直接访问,但类型系统认为MyClass的完整类型定义包含了所有声明的成员,所以你的Stub对象必须包含这些成员才能匹配类型。

另外还有个关键点:TypeScript的私有成员带有“身份标识”,只有通过new MyClass()创建的实例,才会被认为拥有该类的私有成员。哪怕你手动给Stub对象加上private a(),也会因为不是同一个类实例的私有成员而不通过检查。

解决方法

方法1:使用类型断言绕开检查

测试场景下如果只关心公共方法的行为,可以直接用类型断言把Stub对象转为目标类类型:

const test = { b: () => 2 } as MyClass;

这种方式简单直接,适合快速编写测试,缺点是会暂时关闭该对象的类型校验,不过测试中一般只调用公共方法,不会有风险。

方法2:提取公共接口(推荐)

把类的公共成员抽象成接口,让类实现这个接口,测试时用接口类型约束Stub对象:

interface IMyClass {
  b(): number;
}

class MyClass implements IMyClass {
  private a() {
    return 1;
  }

  public b() {
    return 2;
  }
}

// 测试时用接口类型,不需要关心私有成员
const test: IMyClass = { b: () => 2 };

这种方式更符合面向接口编程的原则,同时让测试代码只依赖公共契约,和类的具体实现解耦。

方法3:用测试框架的Mock工具

如果使用Jest、Sinon这类测试框架,可以直接用框架提供的Mock工具来生成Stub:
比如Jest的写法:

jest.mock('./MyClass', () => {
  return {
    MyClass: jest.fn().mockImplementation(() => ({
      b: jest.fn().mockReturnValue(2)
    }))
  };
});

框架会自动处理类的类型匹配,不需要手动处理私有成员。

内容的提问来源于stack exchange,提问作者Sámal Rasmussen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 10:01:20