Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

expect.extend: not possible to correctly extend corresponding TypeScript types #10642

Closed
NaridaL opened this issue Oct 18, 2020 · 4 comments · Fixed by #11211
Closed

expect.extend: not possible to correctly extend corresponding TypeScript types #10642

NaridaL opened this issue Oct 18, 2020 · 4 comments · Fixed by #11211

Comments

@NaridaL
Copy link

NaridaL commented Oct 18, 2020

🐛 Bug Report

When extending expect

import expect from "expect"
expect.extend({
  toWorkProperly(received: number, actual: number) {
    return {pass:true}
  }
})

it should be possible to extend the corresponding types:

declare module "expect" {
  interface Matchers<R> {
    toWorkProperly(actual: number): void
  }
}

instead you get
image

To Reproduce

see above

Expected behavior

There should be no error and proper typechecking.

The reason for the issue, is that expect doesn't actually export the Matchers interface which expect() returns, but rather a sub-interface. See https://github.com/SimenB/jest/blob/master/packages/expect/src/index.ts#L426 .

Unfortunately, it isn't possible to do the right thing directly here, i.e., you can't re-export an interface in a namespace. The quick option would be to move the Matchers declaration directly into the namespace instead of importing it from './types'. The proper solution would probably be to use a proper ES export for expect.

Link to repl or repo (highly encouraged)

repl.it link clicky clicky

envinfo

 npx envinfo --preset jest
npx: installed 1 in 4.202s

  System:
    OS: Linux 5.4 Debian GNU/Linux 9 (stretch) 9 (stretch)
    CPU: (4) x64 Intel(R) Xeon(R) CPU @ 2.30GHz
  Binaries:
    Node: 12.18.3 - /usr/local/bin/node
    Yarn: 1.22.4 - /usr/local/bin/yarn
    npm: 6.14.6 - /usr/local/bin/npm
  npmPackages:
    jest: ^26.5.3 => 26.5.3 

 
@SimenB
Copy link
Member

SimenB commented Oct 18, 2020

Yep, we need to figure out a good story for extending matchers for DefinitelyTyped/DefinitelyTyped#44365 (comment). I haven't spend any time on trying to come up with a good solution for it. We need to both support importing from expect like you do in the OP and import {expect} from '@jest/globals'. Would love some help with coming up with a good solution for this!

@NaridaL
Copy link
Author

NaridaL commented Nov 1, 2020

@SimenB is changing the main export for jest an option? This would be a breaking change for expect. For users either not importing expect at all (relying on globals), or importing it from @jest/globals, it shouldn't require any changes. I assume these are the majority of cases.

This would make extending easily possible. It would also simplify this package. Merging the types and implementation (which are currently separate) might also be possible.

@ajubin
Copy link
Contributor

ajubin commented Mar 18, 2021

Hi,

I've encountered the same situation, it seems that the problem is a typescript problem with Declaration Merging. (see more here microsoft/TypeScript#26660 (comment))

I've create a jest.d.ts file with following content.

What worked for me

declare namespace jest {
  interface Matchers<R> {
    toWorkProperly(a: number): R;
  }
}

and

declare global {
  namespace jest {
    interface Matchers<R> {
      toWorkProperly(a: number): R;
    }
  }
}

export {};

What doesn't work

declare global {
  namespace jest {
    interface Matchers<R> {
      toWorkProperly(a: number): R;
    }
  }
}

and

declare namespace jest {
  interface Matchers<R> {
    toWorkProperly(a: number): R;
  }
}

export {};

I don't understand precisely the root cause, it seems to be linked to how ts handles modules and types files;

ajubin added a commit to ajubin/jest that referenced this issue Mar 18, 2021
Update doc to add types for custom matchers

Fix : jestjs#10642
@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 10, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants