fix(jest-mock): walk overloads in ResolveType/RejectType#16237
Open
tsushanth wants to merge 5 commits into
Open
fix(jest-mock): walk overloads in ResolveType/RejectType#16237tsushanth wants to merge 5 commits into
tsushanth wants to merge 5 commits into
Conversation
Closes jestjs#16174. `ReturnType<T>` picks the LAST overload signature of `T`. For functions like `pg.Client['end']` whose overloads are `(): Promise<void>` and `(cb): void`, `ReturnType` collapses to `void` and the Promise-shaped overload disappears — `mockResolvedValue` / `mockRejectedValue` then infer `never` and reject any value (`TS2345: Argument of type Error is not assignable to parameter of type never`). Introduce `OverloadedReturnType<T>` that walks up to four call signatures and unions their return types, then keep the existing PromiseLike check through `Extract<..., PromiseLike<any>>` so the Promise-shaped overload survives even when a later non-Promise overload exists. Existing typetests covering single-signature functions (sync and async) remain unchanged; a new regression test pins the overload behavior. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
|
✅ Deploy Preview for jestjs ready!Built without sensitive environment variables
To edit notification comments on pull requests, go to your Netlify project configuration. |
babel-jest
babel-plugin-jest-hoist
babel-preset-jest
create-jest
@jest/diff-sequences
expect
@jest/expect-utils
jest
jest-changed-files
jest-circus
jest-cli
jest-config
@jest/console
@jest/core
@jest/create-cache-key-function
jest-diff
jest-docblock
jest-each
@jest/environment
jest-environment-jsdom
@jest/environment-jsdom-abstract
jest-environment-node
@jest/expect
@jest/fake-timers
@jest/get-type
@jest/globals
jest-haste-map
jest-jasmine2
jest-leak-detector
jest-matcher-utils
jest-message-util
jest-mock
@jest/pattern
jest-phabricator
jest-regex-util
@jest/reporters
jest-resolve
jest-resolve-dependencies
jest-runner
jest-runtime
@jest/schemas
jest-snapshot
@jest/snapshot-utils
@jest/source-map
@jest/test-result
@jest/test-sequencer
@jest/transform
@jest/types
jest-util
jest-validate
jest-watcher
jest-worker
pretty-format
commit: |
Lint failure on the original commit: @typescript-eslint/array-type forbids any[] in source. Use Array<any> instead, plus break the long Extract<...> extends PromiseLike<infer U> line per prettier (162 chars). No behavioural change to OverloadedReturnType / ResolveType / RejectType.
Previous version used Extract<...> extends PromiseLike<infer U>, which distributes over never: when the function's return type isn't a PromiseLike at all, Extract collapses to never, and never extends PromiseLike<infer U> resolves with infer U = unknown, not never. That made mockResolvedValue / mockRejectedValue callable on plain non-Promise functions like () => 'value' and broke the __typetests__ assertions that the pre-fix behaviour kept uncallable. Wrap the Extract result in [...] to short-circuit the never case explicitly: [Extract<..., PromiseLike<any>>] extends [never] ? never : ...continues with the PromiseLike inference. Single-signature non-Promise functions now resolve to never as before, and the overload walking still works for the pg.Client-style cases this PR fixes.
Hand-formatting of the [Extract<...>] extends [never] guard didn't match prettier's preferred multi-line tuple shape. Apply `prettier --write` to the file so the lint check is satisfied. No semantic change.
Local re-format used a newer prettier version that wraps interface extends differently from the repo-locked 3.8.3 in yarn.lock. Run `prettier --write` with the pinned version + the project's package.json config so the lint step is clean.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #16174.
Summary
ReturnType<T>picks the last overload signature ofT. For functions likepg.Client['end']whose overloads are(): Promise<void>and(cb): void,ReturnTypecollapses tovoid— the Promise-shaped overload disappears,ResolveType/RejectTypeboth infernever, andmockResolvedValue/mockRejectedValuereject any value withTS2345: Argument of type Error is not assignable to parameter of type never.Fix
Introduce
OverloadedReturnType<T>that walks up to four call signatures and unions their return types. Then keep the existing PromiseLike check throughExtract<..., PromiseLike<any>>so:mockResolvedValueon a sync overload still infersnever.mockResolvedValueinfers the resolvedU,mockRejectedValueinfersunknown(matching the historical contract).Four overload arities should cover the long tail —
pg.Client['end']has 2, most DOM/Node APIs cap at 3-4. If anyone needs more, the pattern extends mechanically.Test plan
Added one typetest in
packages/jest-mock/__typetests__/mock-functions.test.ts:The existing typetests at lines 78-90 and 479-531 (single-signature sync vs async functions) continue to assert the same contract — sync-only functions still reject any resolve/reject value, async functions still narrow the resolve type to the resolved
U.I wasn't able to run
yarn build:js/yarn test-typeslocally (disk space exhausted on my machine). CI should covertypecheck:testsand the tstyche suite — happy to amend if anything surfaces.