How to let know typescript compiler about jest custom matchers?

懵懂的女人 提交于 2020-02-24 03:43:08

问题


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 };
            }
        };
    }
};

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

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

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;
    }
}

which hasn't worked for me.

Do you have any idea?


回答1:


Try this:

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);
   });
});

Notes:

  • 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.


来源:https://stackoverflow.com/questions/59495104/how-to-let-know-typescript-compiler-about-jest-custom-matchers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!