jest-extended: Type definitions not working

  • package version: jest-extended 3.1.0
  • node version: v17.5.0
  • npm (or yarn) version: yarn 3.2.2
  • typescript: 4.8.4

I followed the instructions to use jest-extended with TypeScript shown on the project home page:

// global.d.ts
import 'jest-extended'

I also tried the triple slash directive using types as suggested in the documentation if the above doesn’t work, and tried using a triple slash directive with a path directive to directly import the types from node_modules//jest-extended/types/index.d.ts.

I get the following error message:

test/jest/__tests__/jsdom-env/state.spec.ts:33:18 - error TS2339: Property 'toBeTrue' does not exist on type 'Matchers<void> & SnapshotMatchers<void, boolean> & Inverse<JestMatchers<void, boolean>> & PromiseMatchers<boolean>'.

    33     expect(true).toBeTrue()

I am certain my types directory is being included. I have this typeRoots directive in my common TypeScript config:

  "typeRoots": ["./@types/**/*.d.ts", "./node_modules/@types/**/*.d.ts"],

I also have a custom matcher with a type definition in my global @types folder, and it works fine:

// @types/jest/globals/extend.d.ts
declare module 'expect' {
  export interface Matchers<R> {
    toHaveInProtoChain(...chain: Constructor[]): R
  }
}

I noticed that the signature for my (working) custom matcher is different than the type provided by jest-extended:

declare namespace jest {
  interface Matchers<R> {
    ...

Any help in figuring out why I can’t use the Jest extended matchers is greatly appreciated!

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Reactions: 2
  • Comments: 16 (3 by maintainers)

Most upvoted comments

Hi, I got the issue when I start importing expect from @jest/globals.

import {describe, expect, test} from '@jest/globals'

It works fine if I use @types/jest and don’t import directly from @jest/globals

Here is a mini repo to reproduce the issue. https://github.com/Yupeng-li/jest-extended-type-issure-mini-repo

@krisztianb I’m not sure we’re talking about the exact same issue. I don’t have Cypress in my project, so at least in my case I can’t be having conflicts between it and Jest.

Also, I’m not having issues with ESLint throwing errors, I simply can’t get Typescript itself to compile without the workaround I shared.

I was having the same issue that was fixed by using jest globals instead of importing from @jest/globals like @Yupeng-li said.

However, I was able to work around it with the following declaration file:

// jest-extended.d.ts

import * as matchers from "jest-extended";

declare module "expect" {
	type JestExtendedMatchers = typeof matchers;`
	export interface Matchers<R> extends JestExtendedMatchers {}
}

It appears jest-extended extends the Matchers interface in the jest namespace, but the matchers aren’t actually defined in that namespace when imported from @jest/globals.

@Blond11516 thank you for the help.

I can import SomeType the way you showed in my test files without error. However I still get this error message when accessing anything from jest-expect:

Property ‘toContainKeys’ does not exist on type ‘JestExpect’.

One thing that is special in my case is that I must import from @jest/globals because in our project we are using cypress (that uses Chai) which also has an expect object with different methods.

Update

I found the problem. The issue was that our test folders were excluded in tsconfig so that they are not compiled. After I removed that exclude the following content of jest-extended.d.ts works now for me too:

import * as matchers from "jest-extended";

declare module "expect" {
    type JestExtendedMatchers = typeof matchers;

    export interface AsymmetricMatchers extends JestExtendedMatchers {}

    export interface Matchers<R> extends JestExtendedMatchers {}
}

I ended up adding the matchers I need as manual types:

// @types/@jest/globals/expect.d.ts
declare module 'expect' {
  export interface Matchers<R> {
    /**
     * jest-extended typings do not work, so used matchers are manually included:
     * https://github.com/jest-community/jest-extended/issues/447
     * https://github.com/jest-community/jest-extended/issues/408
     */
    toBeNil(): R
    toBeObject(): R
    ...
  }
}

And adding the @types directory to my tsconfig typeRoots config. I found this library that says that to ensure the global jest declaration is augmented correctly, the Jest setup file with the expect.extend('...') statement for the matchers should be included via your TypeScript configuration:

"include": ["config/jest/setupJest.ts", "..."],

I’m still hoping to find a better solution than adding manual types for the matchers. I haven’t tried the approach mentioned above to see if it works though.

I have the same problem. I don’t see how the type declarations (which obviously need to work through TS’s declaration merging) of this package could possibly work. But I guess I’m missing something because otherwise more people would complain about this issue. @webstackdev have you already found a solution?