如何为ts-sinon的mock正确指定同时兼容原类和存根方法的类型
解决方案
正确的类型直接使用sinon.StubbedInstance<Foo>即可,不需要和原类做联合类型拼接。
你之前使用Foo | sinon.StubbedInstance<Foo>失效的原因:
联合类型只会保留两个类型的共有成员,
StubbedInstance<Foo>本身已经内置了原Foo类的所有实例属性,还额外拓展了stub相关的方法属性;加了| Foo之后,TS会判定方法可能是Foo类的普通函数,自然识别不到returns这类stub专属API。
修改后的代码示例:
import { expect } from 'chai'; import * as sinon from 'ts-sinon' class Foo { public getFoo(): string { return 'foo'; } } describe('Foo', () => { it('can mock methods on Foo', () => { // 直接指定为StubbedInstance类型即可 let foo: sinon.StubbedInstance<Foo> = sinon.stubConstructor(Foo); foo.getFoo.returns('bar'); expect(foo.getFoo()).to.equal('bar'); }); });
额外优化建议:
- 如果使用ts-sinon v2及以上版本,可以直接去掉手动类型标注,TS会自动从
stubConstructor的返回值推导正确类型,代码可以简化为let foo = sinon.stubConstructor(Foo); - 可以提前定义全局类型别名减少重复代码:
type Stubbed<T> = sinon.StubbedInstance<T>,使用时直接写let foo: Stubbed<Foo>即可 - 如果指定
StubbedInstance<Foo>后仍有类型报错,请先升级ts-sinon到2.x及以上正式版本,旧版本的类型定义存在兼容问题
内容的提问来源于stack exchange,提问作者lyte
相关产品推荐
相关产品推荐

