React Query useMutation - "No overload matches this call"
Asked Answered
E

2

5

I'm using react-query in a typescript project, and am getting a hard to interpret type error when trying to use the useMutation() hook with a graphql query.

Example Code:

useMutation(
    async (
      parameter1: string,
      parameter2: string
    ) => {
      const response = await sdk.myMutation({
        parameter1: parameter1,
        parameter2: parameter2,
      });
      return response;
    },
    {
      onSettled: () => queryClient.invalidateQueries([CACHE_KEY]),
    }
);

Type Error:

  No overload matches this call.
  Overload 1 of 4, '(mutationFn: MutationFunction<{ __typename: "IdResponse"; id: string; }, string>, options?: Omit<UseMutationOptions<{ __typename: "IdResponse"; id: string; }, unknown, string, unknown>, "mutationFn"> | undefined): UseMutationResult<...>', gave the following error.
    Argument of type '(parameter1: string, parameter2: string) => Promise<{ __typename: "IdResponse"; id: string; }>' is not assignable to parameter of type 'MutationFunction<{ __typename: "IdResponse"; id: string; }, string>'.
  Overload 2 of 4, '(mutationKey: MutationKey, options?: Omit<UseMutationOptions<unknown, unknown, void, unknown>, "mutationKey"> | undefined): UseMutationResult<unknown, unknown, void, unknown>', gave the following error.
    Argument of type '(parameter1: string, parameter2: string) => Promise<{ __typename: "IdResponse"; id: string; }>' is not assignable to parameter of type 'MutationKey'.
  Overload 3 of 4, '(mutationKey: MutationKey, mutationFn?: MutationFunction<unknown, void> | undefined, options?: Omit<UseMutationOptions<unknown, unknown, void, unknown>, "mutationFn" | "mutationKey"> | undefined): UseMutationResult<...>', gave the following error.
    Argument of type '(parameter1: string, parameter2: string) => Promise<{ __typename: "IdResponse"; id: string; }>' is not assignable to parameter of type 'MutationKey'.
Emelinaemeline answered 14/10, 2022 at 3:50 Comment(0)
E
9

Although not obvious to me, the problem was that I tried to pass multiple parameters to the function used in useMutation.

The MutationFunction type only accepts a single parameter (confusingly called variables). https://tanstack.com/query/v4/docs/reference/useMutation

To fix the problem I passed an object containing my parameters to the function like this:

useMutation(
    async ({
      parameter1,
      parameter2
    }:{
      parameter1: string,
      parameter2: string
      }
    ) => {
      const response = await sdk.myMutation({
        parameter1: parameter1,
        parameter2: parameter2,
      });
      return response;
    },
    {
      onSettled: () => queryClient.invalidateQueries([CACHE_KEY]),
    }
);

A cleaner idea might be to create a type to hold these parameters something like.

type myMutationParams ={
  parameter1: string;
  parameter2: string;
}

Then the useMutation hook looks something like this:

useMutation(
    async ({
      parameter1,
      parameter2
    }: myMutationParams
    ) => {
      const response = await sdk.myMutation({
        parameter1: parameter1,
        parameter2: parameter2,
      });
      return response;
    },
    {
      onSettled: () => queryClient.invalidateQueries([CACHE_KEY]),
    }
);
Emelinaemeline answered 14/10, 2022 at 3:57 Comment(1)
Many thanks for this example! Was dealing with the same issueHegelian
K
4

For me it usually happens when, I have any callback functions like onError, onSuccess or onSetteled.

  • Fix the typing, remove any types assigned in parameter.

For example:

// This is incorrect
onSettled: (_, err: CustomError) => {
 
},
// This is correct
onSettled: (_, err) => {
  const newErr = err as CustomError;
  // Now you can use the newErr
},

Check for types in mutationFn:

For example:

// This is incorrect
mutationFn: (accountId: string, accountDetails: Account) => {

},
// This is correct
type MutationParams = {
  accountId: string;
  accountDetails: Account;
};
mutationFn: (requestBody: MutationParams) => {
  // Now you can destructure param.
},
  • Be sure to only use one param, so just combine multiple params into object.
Kial answered 10/8, 2023 at 9:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.