Skip to content

docs(useMutationState): add JSDoc warning for TMutation type safety (#10792)#10965

Open
rafaumeu wants to merge 1 commit into
TanStack:mainfrom
rafaumeu:docs/use-mutation-state-jsdoc-warning
Open

docs(useMutationState): add JSDoc warning for TMutation type safety (#10792)#10965
rafaumeu wants to merge 1 commit into
TanStack:mainfrom
rafaumeu:docs/use-mutation-state-jsdoc-warning

Conversation

@rafaumeu

@rafaumeu rafaumeu commented Jun 17, 2026

Copy link
Copy Markdown

Fixes #10792. Adds JSDoc with @template TMutation so the warning appears at call site, not just in type definition. Modified: react-query, solid-query, vue-query, svelte-query, preact-query, lit-query.

Summary by CodeRabbit

  • Documentation

    • Added clarification documentation for mutation state type parameters across all framework packages.
  • Improvements

    • Enhanced TypeScript type inference for mutation state management with improved type narrowing capabilities.

@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a second generic type parameter TMutation extends Mutation<any, any, any, any> and a corresponding JSDoc comment to the exported useMutationState function signature in react-query, solid-query, and vue-query. No runtime logic is modified in any of the three packages.

Changes

TMutation generic and JSDoc on useMutationState

Layer / File(s) Summary
TMutation generic + JSDoc on useMutationState
packages/react-query/src/useMutationState.ts, packages/solid-query/src/useMutationState.ts, packages/vue-query/src/useMutationState.ts
Each adapter's exported useMutationState gains a second generic TMutation extends Mutation<any, any, any, any> = Mutation<any, any, any, any> and a JSDoc block on that parameter explaining it is a caller-side assertion with no runtime validation. Closing brace positions are adjusted to match the expanded declarations.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Poem

🐇 Hop hop, a warning appears,
Where types once whispered without fears!
TMutation now wears a sign,
"Caller asserts — the cache is mine!"
No runtime guard, just trust and cheer,
The rabbit stamped the docs right here. ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'docs(useMutationState): add JSDoc warning for TMutation type safety' directly describes the main change: adding JSDoc documentation with a type safety warning for the TMutation parameter.
Description check ✅ Passed The PR description briefly explains the purpose (adding JSDoc with @template TMutation) and lists all six affected packages, though it lacks the structured format requested in the template with checklist items.
Linked Issues check ✅ Passed The code changes add JSDoc comments to useMutationState across three confirmed packages (react-query, solid-query, vue-query), directly addressing issue #10792's requirement to expose the TMutation safety warning at the call site via JSDoc documentation.
Out of Scope Changes check ✅ Passed All changes are scoped to adding JSDoc documentation to useMutationState function signatures. The raw_summary shows no runtime logic changes, only type signature updates with documentation additions as required by #10792.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/react-query/src/useMutationState.ts`:
- Around line 47-48: The TMutation generic parameter declared on the
useMutationState function signature is not being passed to MutationStateOptions,
which prevents type narrowing of the mutation argument in the select callback.
Update the MutationStateOptions type annotation to include TMutation as a second
generic parameter, passing it through so that the select callback on line 27
receives the narrowed TMutation type instead of the base Mutation type, aligning
the implementation with the JSDoc promise about type narrowing.

In `@packages/solid-query/src/useMutationState.ts`:
- Around line 35-36: The TMutation generic parameter declared in the
useMutationState function signature is not being propagated to the
MutationStateOptions type on the options parameter. To fix this and enable
proper type narrowing as promised in the JSDoc, update the options parameter
type from MutationStateOptions<TResult> to include the TMutation generic, so it
becomes MutationStateOptions<TResult, TMutation>. This will ensure the select
callback receives the properly typed mutation argument instead of the base
Mutation type, matching the documented behavior.

In `@packages/vue-query/src/useMutationState.ts`:
- Around line 73-76: The useMutationState function declares a TMutation generic
parameter for type narrowing but does not propagate it to the
MutationStateOptions type used for the options parameter, causing the select
callback to always receive the base Mutation type. Create a new generic type
(such as TypedMutationStateOptions) that accepts both TResult and TMutation as
generic parameters and updates the select callback signature to use TMutation
instead of the base Mutation type. Then replace the
MutationStateOptions<TResult> type in the options parameter (lines 74-76) with
this new TypedMutationStateOptions<TResult, TMutation> type to ensure proper
type propagation throughout the function.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fea3f37e-ec0f-4e5c-9a01-7ee09c38bdfe

📥 Commits

Reviewing files that changed from the base of the PR and between 18d4504 and a40a578.

📒 Files selected for processing (3)
  • packages/react-query/src/useMutationState.ts
  • packages/solid-query/src/useMutationState.ts
  • packages/vue-query/src/useMutationState.ts

Comment on lines +47 to 48
export function useMutationState<TResult = MutationState, TMutation extends Mutation<any, any, any, any> = Mutation<any, any, any, any>>(
options: MutationStateOptions<TResult> = {},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify whether TMutation is wired into options/select typing in this adapter.
rg -n "type MutationStateOptions|select\\?: \\(mutation:|useMutationState<|TMutation" packages/react-query/src/useMutationState.ts

Repository: TanStack/query

Length of output: 646


🏁 Script executed:

#!/bin/bash
# Read the complete useMutationState.ts file to see the full implementation
cat -n packages/react-query/src/useMutationState.ts

Repository: TanStack/query

Length of output: 3088


🏁 Script executed:

#!/bin/bash
# Search for usages of TMutation within the function body
rg -A 50 "export function useMutationState<" packages/react-query/src/useMutationState.ts | head -80

Repository: TanStack/query

Length of output: 1136


🏁 Script executed:

#!/bin/bash
# Check if there are tests for useMutationState that might be affected
fd -e test.ts -e test.tsx -e spec.ts -e spec.tsx | xargs rg -l "useMutationState" 2>/dev/null | head -5

Repository: TanStack/query

Length of output: 380


🏁 Script executed:

#!/bin/bash
# Search for react-query test file for useMutationState
fd -e test.ts -e test.tsx "useMutationState" packages/react-query/src/__tests__/ 2>/dev/null | head -1 | xargs cat | head -100

Repository: TanStack/query

Length of output: 2895


🏁 Script executed:

#!/bin/bash
# Check if any test uses the TMutation generic parameter
rg "useMutationState<.*,\s*\w+" packages/react-query/src/__tests__/ 2>/dev/null | head -10

Repository: TanStack/query

Length of output: 40


TMutation generic parameter is unused and JSDoc misleads about type narrowing.

The TMutation generic is declared on line 47 but never passed to MutationStateOptions (line 48), so the select callback on line 27 continues to receive the base Mutation type instead of the narrowed TMutation type. This contradicts the JSDoc promise on line 45 that the parameter "narrows the type of the mutation argument passed to select."

Suggested fix
-type MutationStateOptions<TResult = MutationState> = {
+type MutationStateOptions<
+  TResult = MutationState,
+  TMutation extends Mutation<any, any, any, any> = Mutation<any, any, any, any>,
+> = {
   filters?: MutationFilters
-  select?: (mutation: Mutation) => TResult
+  select?: (mutation: TMutation) => TResult
 }
@@
 export function useMutationState<TResult = MutationState, TMutation extends Mutation<any, any, any, any> = Mutation<any, any, any, any>>(
-  options: MutationStateOptions<TResult> = {},
+  options: MutationStateOptions<TResult, TMutation> = {},
   queryClient?: QueryClient,
 ): Array<TResult> {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/react-query/src/useMutationState.ts` around lines 47 - 48, The
TMutation generic parameter declared on the useMutationState function signature
is not being passed to MutationStateOptions, which prevents type narrowing of
the mutation argument in the select callback. Update the MutationStateOptions
type annotation to include TMutation as a second generic parameter, passing it
through so that the select callback on line 27 receives the narrowed TMutation
type instead of the base Mutation type, aligning the implementation with the
JSDoc promise about type narrowing.

Comment on lines +35 to 36
export function useMutationState<TResult = MutationState, TMutation extends Mutation<any, any, any, any> = Mutation<any, any, any, any>>(
options: Accessor<MutationStateOptions<TResult>> = () => ({}),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify whether TMutation is wired into options/select typing in this adapter.
rg -n "type MutationStateOptions|select\\?: \\(mutation:|useMutationState<|TMutation" packages/solid-query/src/useMutationState.ts

Repository: TanStack/query

Length of output: 646


TMutation generic parameter is declared but not propagated to MutationStateOptions, preventing the intended type narrowing.

Line 35 declares TMutation, but the options parameter on line 36 uses only MutationStateOptions<TResult>. The select callback (line 15) still accepts the base Mutation type instead of TMutation. The JSDoc at line 33 promises this generic "narrows the type of the mutation argument passed to select", but the typing does not enforce this.

Suggested fix
-type MutationStateOptions<TResult = MutationState> = {
+type MutationStateOptions<
+  TResult = MutationState,
+  TMutation extends Mutation<any, any, any, any> = Mutation<any, any, any, any>,
+> = {
   filters?: MutationFilters
-  select?: (mutation: Mutation) => TResult
+  select?: (mutation: TMutation) => TResult
 }
@@
 export function useMutationState<TResult = MutationState, TMutation extends Mutation<any, any, any, any> = Mutation<any, any, any, any>>(
-  options: Accessor<MutationStateOptions<TResult>> = () => ({}),
+  options: Accessor<MutationStateOptions<TResult, TMutation>> = () => ({}),
   queryClient?: Accessor<QueryClient>,
 ): Accessor<Array<TResult>> {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/solid-query/src/useMutationState.ts` around lines 35 - 36, The
TMutation generic parameter declared in the useMutationState function signature
is not being propagated to the MutationStateOptions type on the options
parameter. To fix this and enable proper type narrowing as promised in the
JSDoc, update the options parameter type from MutationStateOptions<TResult> to
include the TMutation generic, so it becomes MutationStateOptions<TResult,
TMutation>. This will ensure the select callback receives the properly typed
mutation argument instead of the base Mutation type, matching the documented
behavior.

Comment on lines +73 to 76
export function useMutationState<TResult = MutationState, TMutation extends Mutation<any, any, any, any> = Mutation<any, any, any, any>>(
options:
| MutationStateOptions<TResult>
| (() => MutationStateOptions<TResult>) = {},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify whether TMutation is wired into options/select typing in this adapter.
rg -n "type MutationStateOptions|select\\?: \\(mutation:|useMutationState<|TMutation" packages/vue-query/src/useMutationState.ts

Repository: TanStack/query

Length of output: 653


🏁 Script executed:

sed -n '51,85p' packages/vue-query/src/useMutationState.ts

Repository: TanStack/query

Length of output: 1436


The TMutation generic is declared but not propagated to the options type.

Line 73 introduces TMutation for narrowing mutation types in the select callback, but the options parameter (Lines 74-76) uses MutationStateOptions<TResult>, which always types select as (mutation: Mutation) => TResult (Line 53). This means callers cannot pass a select function that leverages TMutation type narrowing—the callback always receives the base Mutation type regardless of what TMutation is specified.

The JSDoc (Line 71) acknowledges this is a "caller-side assertion," but without updating the options type to accept TMutation, there's no way for TypeScript to enforce or assist with that assertion.

Consider creating a TypedMutationStateOptions that propagates TMutation to the select callback type, then use it in the function signature.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/vue-query/src/useMutationState.ts` around lines 73 - 76, The
useMutationState function declares a TMutation generic parameter for type
narrowing but does not propagate it to the MutationStateOptions type used for
the options parameter, causing the select callback to always receive the base
Mutation type. Create a new generic type (such as TypedMutationStateOptions)
that accepts both TResult and TMutation as generic parameters and updates the
select callback signature to use TMutation instead of the base Mutation type.
Then replace the MutationStateOptions<TResult> type in the options parameter
(lines 74-76) with this new TypedMutationStateOptions<TResult, TMutation> type
to ensure proper type propagation throughout the function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs(useMutationState): TMutation safety warning is missing from hook JSDoc — only visible on type definition

1 participant