query icon indicating copy to clipboard operation
query copied to clipboard

useMutation callbacks context type depends on options object sorting

Open alexw-at opened this issue 10 months ago • 5 comments

Describe the bug

The type of context in the useMutation callbacks depends on the sorting of the options object.

Your minimal, reproducible example

https://codesandbox.io/p/devbox/usemutationcontext-qsnk89

Steps to reproduce

  1. Open minimal reproduction
  2. Open file src/index.tsx or run tsc --noemit
  3. Type of context in callbacks depends options object sorting
  4. first useMutation works as intended, second useMutation has type errors

Expected behavior

The type of context in useMutation callbacks should always be the same and not depend on the options object sorting.

How often does this bug happen?

Every time

Screenshots or Videos

No response

Platform

Seems to be a types only bug. Has no effect on runtime values.

Tanstack Query adapter

react-query

TanStack Query version

5.72.2

TypeScript version

5.8.2

Additional context

No response

alexw-at avatar Apr 10 '25 11:04 alexw-at

Should you define type for it first? Like this

  const { mutate: mutate2 } = useMutation<
    void,
    unknown,
    string,
    { foo: string }
  >({
    mutationFn: async (value: string) => {
      console.log(value);
    },
    onError: (_error, _variables, context) => {
      console.log("onError", context?.foo);
    },
    onSettled: (_data, _error, _variables, context) => {
      console.log("onSettled", context?.foo);
    },
    onMutate: (data) => {
      return { foo: data };
    },
  });

Then the type error will disappear

HanhNguyenHong1802 avatar Apr 10 '25 17:04 HanhNguyenHong1802

Yes this does work and the error disappears. But the inference of TContext still depends on the sorting of the options object.

alexw-at avatar Apr 11 '25 06:04 alexw-at

In an object, type consumers must come after type producers. onMutate produces the type, onError and onSettled consume them. This is a known typescript limitation:

. https://github.com/microsoft/TypeScript/issues/53018#issuecomment-1518558545

We do have an eslint rule for infinite-query-property-order. @schiller-manuel do you think it would be possible to extend this to a more general rule that also covers this use-case?

TkDodo avatar Apr 11 '25 07:04 TkDodo

Thanks for the clarification. An eslint rule would be a nice.

alexw-at avatar Apr 11 '25 07:04 alexw-at

I've created PR #9186

Could you take a look? :)

jochongs avatar May 25 '25 11:05 jochongs