问题
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 callexpect.extend
on every test file.declare global
is necessary becausejest
is not explicitly imported (it is a global import).- The signature of the
toBeTheSameAsRemote
function is not the same insideexpect.extend
and on TypeScript.
来源:https://stackoverflow.com/questions/59495104/how-to-let-know-typescript-compiler-about-jest-custom-matchers