diff --git a/packages/expect/src/asymmetricMatchers.ts b/packages/expect/src/asymmetricMatchers.ts index e0f633d59efe..c8d2dae00625 100644 --- a/packages/expect/src/asymmetricMatchers.ts +++ b/packages/expect/src/asymmetricMatchers.ts @@ -21,20 +21,22 @@ const utils = Object.freeze({ subsetEquality, }); -export abstract class AsymmetricMatcher - implements AsymmetricMatcherInterface +export abstract class AsymmetricMatcher< + T, + State extends MatcherState = MatcherState, +> implements AsymmetricMatcherInterface { $$typeof = Symbol.for('jest.asymmetricMatcher'); constructor(protected sample: T, protected inverse = false) {} - protected getMatcherContext(): MatcherState { + protected getMatcherContext(): State { return { ...getState(), equals, isNot: this.inverse, utils, - }; + } as State; } abstract asymmetricMatch(other: unknown): boolean; diff --git a/packages/expect/src/index.ts b/packages/expect/src/index.ts index 9b86118551d2..9b779ddfea92 100644 --- a/packages/expect/src/index.ts +++ b/packages/expect/src/index.ts @@ -354,8 +354,9 @@ const makeThrowingMatcher = ( } }; -expect.extend = (matchers: MatchersObject): void => - setMatchers(matchers, false, expect); +expect.extend = ( + matchers: MatchersObject, +): void => setMatchers(matchers, false, expect); expect.anything = anything; expect.any = any; @@ -396,8 +397,10 @@ function assertions(expected: number) { Error.captureStackTrace(error, assertions); } - getState().expectedAssertionsNumber = expected; - getState().expectedAssertionsNumberError = error; + setState({ + expectedAssertionsNumber: expected, + expectedAssertionsNumberError: error, + }); } function hasAssertions(...args: Array) { const error = new Error(); @@ -406,8 +409,10 @@ function hasAssertions(...args: Array) { } matcherUtils.ensureNoExpected(args[0], '.hasAssertions'); - getState().isExpectingAssertions = true; - getState().isExpectingAssertionsError = error; + setState({ + isExpectingAssertions: true, + isExpectingAssertionsError: error, + }); } // add default jest matchers diff --git a/packages/expect/src/jestMatchersObject.ts b/packages/expect/src/jestMatchersObject.ts index 7492957eaaec..370802661c30 100644 --- a/packages/expect/src/jestMatchersObject.ts +++ b/packages/expect/src/jestMatchersObject.ts @@ -37,18 +37,21 @@ if (!global.hasOwnProperty(JEST_MATCHERS_OBJECT)) { }); } -export const getState = (): MatcherState => +export const getState = (): State => (global as any)[JEST_MATCHERS_OBJECT].state; -export const setState = (state: Partial): void => { +export const setState = ( + state: Partial, +): void => { Object.assign((global as any)[JEST_MATCHERS_OBJECT].state, state); }; -export const getMatchers = (): MatchersObject => - (global as any)[JEST_MATCHERS_OBJECT].matchers; +export const getMatchers = < + State extends MatcherState = MatcherState, +>(): MatchersObject => (global as any)[JEST_MATCHERS_OBJECT].matchers; -export const setMatchers = ( - matchers: MatchersObject, +export const setMatchers = ( + matchers: MatchersObject, isInternal: boolean, expect: Expect, ): void => { @@ -62,7 +65,8 @@ export const setMatchers = ( // expect is defined class CustomMatcher extends AsymmetricMatcher< - [unknown, ...Array] + [unknown, ...Array], + State > { constructor( inverse: boolean = false,