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

[BUG] Incorrect return type output when using jest.mocked #825

Open
2 tasks done
veksa opened this issue Oct 29, 2024 · 8 comments
Open
2 tasks done

[BUG] Incorrect return type output when using jest.mocked #825

veksa opened this issue Oct 29, 2024 · 8 comments
Labels
bug more info needed Issue not actionable w/out additional details wontfix

Comments

@veksa
Copy link

veksa commented Oct 29, 2024

Before you begin...

  • I have searched the existing issues
  • I am not using version 13.x of node (if so, please upgrade)

Description of the problem

Incorrect return type output when using jest.mocked (Uint8Array instead of string)

for example:
jest.mocked(v4).mockReturnValue('str');

in webstorm:
image

suggesting use of generic to typify buf as it was in @types/uuid:

function v4<T>(options?: Version4Options, buf?: T, offset?: number): T;

instead

function v4(options?: Version4Options, buf?: Uint8Array, offset?: number): Uint8Array;

Recipe for reproducing

1. install uuid
2. setup jest
3. use `jest.mocked(v4).mockReturnValue('str');`

Additional information

No response

Environment

No response

@veksa veksa added the bug label Oct 29, 2024
@broofa
Copy link
Member

broofa commented Oct 29, 2024

Incorrect return type output when using jest.mocked (Uint8Array instead of string)

I think this is the gist of the problem. But that's a jest issue, not an issue with this project.

The TS types bundled with uuid@11 are auto-generated by tsc from the source code, and are an accurate reflection of what is permitted by the uuid API.

If this worked before, it's only because the [hand-rolled] types defined in @types/uuid were structured in a way that didn't trigger this problem for jest.

function v4(options?: Version4Options, buf?: T, offset?: number): T;

I'm gonna give this a pretty hard "no". Unnecessarily loose types are less helpful and generally considered a code smell. This is also not how v4() is defined in @types/uuid, which is a bit more complicated.

That said, I'll tentatively suggest you could put up a PR if you wanted to propose some alternate incantations for the function overloads in src/v4.ts and I'll take a look. Just be aware my priority is that the types accurately reflect the allowable inputs and outputs of that method, and the code needs to npm build. And also, I say "tentatively" because as I said I'm not convinced this is an issue this project should be trying to solve.

I'll leave this issue open for the time being as it seems other people may be affected by this. For immediate paths forward, I'd suggest one or more of the following:

  • Look into jest's mocking utils to see if there's a workaround of some sort
  • Open an issue with the jest project to see what they suggest
  • Pin your dependencies to uuid@10 and @types/uuid@10

@broofa broofa added wontfix more info needed Issue not actionable w/out additional details labels Oct 29, 2024
@robbtraister
Copy link
Contributor

There is a typing cleanup that can be applied to the v4 signature where options and buf are required for the Uint8Array case. Unfortunately, it will not fix this issue (since the mock could still be called with arguments), but it will enforce stricter result values for calls of v4()

@broofa
Copy link
Member

broofa commented Nov 1, 2024

There is a typing cleanup that can be applied to the v4 signature where options and buf are required for the Uint8Array

@robbtraister Can you elaborate?

@robbtraister
Copy link
Contributor

There is a typing cleanup that can be applied to the v4 signature where options and buf are required for the Uint8Array

@robbtraister Can you elaborate?

#831

@mh1622
Copy link

mh1622 commented Nov 18, 2024

As a workaround, you can use type assertion to bypass the compiler error. Not ideal, obviously.

(v4 as jest.Mock).mockReturnValue('uuid');

@pbechliv
Copy link

There is a typing cleanup that can be applied to the v4 signature where options and buf are required for the Uint8Array

@robbtraister Can you elaborate?

#831

I tried with version 11.0.3 which includes the mentioned PR changes and the typing issue still persists in Jest

@robbtraister
Copy link
Contributor

There is a typing cleanup that can be applied to the v4 signature where options and buf are required for the Uint8Array

@robbtraister Can you elaborate?

#831

I tried with version 11.0.3 which includes the mentioned PR changes and the typing issue still persists in Jest

Sorry for any confusion. The fix in 11.0.3 ensures that a string is returned when v4() (or other versions) is invoked with no arguments. However, as I suggested in my original comment, it will not fix the mocking issue. The test runner cannot guarantee that your code only ever invokes the function with no arguments, so your mock must support the entire range of signatures of the original function. I would suggest looking into covariance to better understand.

A possible workaround is to create your own function that wraps v4 and mock it. Because this only ever invokes the original function with no arguments, it is guaranteed to return a string.

import { v4 as uuidV4 } from "uuid";

export function v4(): string {
  return uuidV4();
}

@lg-kialo
Copy link

lg-kialo commented Nov 28, 2024

Another scenario in which the new types are quite annoying:

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug more info needed Issue not actionable w/out additional details wontfix
Projects
None yet
Development

No branches or pull requests

6 participants