如何让TypeScript知道自定义Jest匹配器? [英] How to let TypeScript know about custom Jest matchers?

查看:257
本文介绍了如何让TypeScript知道自定义Jest匹配器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用jest的react/typescript项目,其中有一个自定义匹配项,例如:

I have a react/typescript project, using jest, where I have a custom matcher like:

export const MyCustomMatchers = {
    toBeTheSameAsRemote: function(_util: any, _customEqualityTesters: any) {
        return {
            compare: function(actual: Brand, expected: RemoteBrand) {
                const pass: boolean = attributesMatch(actual, expected);
                const message: string = pass
                    ? 'Local matches Remote'
                    : 'Local does not match Remote';

                return { pass, message: () => message };
            }
        };
    }
};

我在测试中通过在describe函数中进行引用的方式来引用

:

which I reference in my tests by doing inside the describe function:

beforeEach(() => {
  jasmine.addMatchers(MyCustomMatchers);
});

并在it函数中像这样使用:

And use like this in it functions:

expect(localValue).toBeTheSameAsRemote(remoteValue);

测试正常运行,但是打字稿编译器无法识别匹配器,这很有意义,因为我没有在类型系统中的任何地方定义它

Tests run properly, but typescript compiler does not recognize the matcher, which makes sense cuz I haven't defined it anywhere in the types system

Property 'toBeTheSameAsRemote' does not exist on type 'JestMatchersShape<Matchers<void, MyType[]>, Matchers<Promise<void>, MyType[]>>'.ts(2339)

到目前为止,我发现的内容与扩展茉莉花和/或开玩笑的名称空间有关,例如

What I have found so far relates to extending the namespace for jasmine and/or jest, e.g.

declare namespace jasmine {
    interface Matchers {
        toBeTheSameAsRemote(remote: any): any;
    }
}

这对我没有用.

你有什么主意吗?

推荐答案

尝试一下:

以下文件声明了实际的 实现expect.extend以及TypeScript声明.

The following file declares both the actual implementation expect.extend and also the TypeScript declaration.

custom-matcher.ts:

declare global {
  namespace jest {
    interface Matchers<R> {
        toBeTheSameAsRemote: (expected: string) => CustomMatcherResult;
    }
  }
}

expect.extend({
    /**
     * Notice that this implementation has 2 arguments, but the implementation inside the Matchers only has 1
     */
    toBeTheSameAsRemote(
    received: string,
    expected: string
  ) {
    return {
      pass: false,
      message: "A GraphQl error was expected"
    };
  }
});

// I am exporting nothing just so we can import this file
export default undefined;

现在,在测试文件中,导入上述模块.

Now, on your test file, import the above module.

actual-test.ts:

// importing the custom matcher file is important
import "../../testing/custom-matchers/custom-matcher";

describe("something", () => {
   it("should work", () => {
       expect(localValue).toBeTheSameAsRemote(remoteValue);
   });
});

注意:

  • expect.extend将从导入中自动调用.无需在每个测试文件上调用expect.extend.
  • declare global是必需的,因为未明确导入jest(它是全局导入).
  • toBeTheSameAsRemote函数的签名在expect.extend内部和TypeScript上都不相同.
  • expect.extend will be called automatically from the import. There is no need to call expect.extend on every test file.
  • declare global is necessary because jest is not explicitly imported (it is a global import).
  • The signature of the toBeTheSameAsRemote function is not the same inside expect.extend and on TypeScript.

这篇关于如何让TypeScript知道自定义Jest匹配器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆