打字稿原型补丁和玩笑

时间:2020-04-25 09:22:31

标签: typescript unit-testing jestjs prototype ts-jest

我有一个玩笑,无法正确识别合并的接口。

我有一个使用npm安装的@ types /库中的declecle文件。 该实现是由环境作为生产系统中的全局环境来实现的,而我无法访问它(将window视为等效的浏览器,它在代码中未定义,但是当js在浏览器中运行时同样存在)

// @types/Foo/index.d.ts

interface Foo {
  A();
}

然后我使用原型向该接口添加更多功能

// src/monkeypatch.ts

declare global {
  interface Foo {
    B();
  }
}
Foo.prototype.B = function() {};

并在我的代码中使用它

// main.ts
import 'src/monkeypatch.ts'; // side effects import
// src/Bar.ts

class Bar {
  bar(foo: Foo) {
    foo.B();
  }
}

到目前为止,一切都按预期进行,我的编辑很满意,tsc很满意,并且一切在生产中都运行良好。

现在,我想设置单元测试并模拟单元测试的实现,我创建一个实现。

// mocks/Foo.ts

class FooImpl implements Partial<Foo> {
  A() {};
}

export { FooIMpl as Foo };

和测试文件

// src/Bar.spec.ts

import { Foo } from '../mocks/Foo';
(global as any).Foo = Foo;
import 'monkeypatch';  // patches A with additional methods

import { Bar } from 'Bar';

new Bar().bar(new Foo());

但是我收到以下错误,好像它不知道接口已合并或已被修补的事实一样。

'FooImpl'类型的参数不能分配给'Foo'类型的参数。 类型“ FooImpl”缺少类型“ Foo”中的以下属性:B。 ts(2345)

将呼叫站点更改为bar(new Foo() as any);是一种解决方法,可以使测试通过,但闻起来很恐怖,我希望它能够正常工作,我想念什么?

另一个问题是我似乎必须使用Partial使编译器满意,否则会出现以下错误: 类“ FooImpl”错误地实现了接口“ Foo”。 类型“ FooImpl”缺少类型“ Foo”中的以下属性:B

1 个答案:

答案 0 :(得分:0)

似乎修补了 ,但是您的FooImpl只是定义A(){},而不是B(){}自己定义的src/monkeypatch.ts

增强后,Foo变为

class Foo {
  A() {}
  B() {}
}

因此要将FooImpl分配给Foo,您应该同时实现这两者。