I am trying to add a custom matcher to Jest in Typescript. This works fine, but I can\'t get Typescript to recognize the extended Matchers.
myMatcher.ts
OK, so there are a few issues here
When a source file (.ts or .tsx) file and a declaration file (.d.ts) file are both candidates for module resolution, as is the case here, the compiler will resolve the source file.
You probably have two files because you want to export a value and also modify the type of the global object jest. However, you do not need two files for this as TypeScript has a specific construct for augmenting the global scope from within a module. That is to say, all you need is the following .ts file
myMatcher.ts
// use declare global within a module to introduce or augment a global declaration.
declare global {
namespace jest {
interface Matchers {
myMatcher: typeof myMatcher;
}
}
}
export default function myMatcher(this: jest.MatcherUtils, received: T, expected: T) {
const pass = received === expected;
return {
pass,
message: () => `expected ${pass ? '!' : '='}==`
};
}
That said, if you have such a situation, it is a good practice to perform the global mutation and the global type augmentation in the same file. Given that, I would consider rewriting it as follows
myMatcher.ts
// ensure this is parsed as a module.
export {};
declare global {
namespace jest {
interface Matchers {
myMatcher: typeof myMatcher;
}
}
}
function myMatcher(this: jest.MatcherUtils, received: T, expected: T) {
const pass = received === expected;
return {
pass,
message: () => `expected ${pass ? '!' : '='}==`
};
}
expect.extend({
myMatcher
});
someTest.ts
import './myMatcher';
it('should work', () => {
expect('str').myMatcher('str');
});