How to declare useMutation return type in 'react-query'

Viewed 8999

Given the following code:

const setFriendCode = (data: Params) => api({ data })
const [mutateSetFriendCode, state] = useMutation<Response, Params>(
  setFriendCode
)

Argument of type '(data: Params) => Promise' is not assignable to parameter of type 'MutationFunction<Response, undefined>'. Types of parameters 'data' and 'variables' are incompatible. Type 'undefined' is not assignable to type 'Params'.ts(2345)

To avoid the compilation error I used.

const setFriendCode = (data?: Params) => api({ data })
const [mutateSetFriendCode, state] = useMutation<Response, Params>(
  setFriendCode
)

but I want to give 'data' as a required.

How to remove the question mark on data?

2 Answers

It looks like you are trying to match this overload (2 of 4):

export declare function useMutation<
  TData = unknown, 
  TError = unknown, 
  TVariables = void, 
  TContext = unknown
>(
  mutationFn: MutationFunction<TData, TVariables>, 
  options?: UseMutationOptions<TData, TError, TVariables, TContext>
): UseMutationResult<TData, TError, TVariables, TContext>;

The useMutation hook has 4 generic type parameters. I think you intended to use Params as TVariables but you are actually using it as TError when you put it in the second position of useMutation<Response, Params>(). That's why you wind up with an unknown in the type for the MutationFunction which represents TVariables.

The signature of the function is:

export declare type MutationFunction<
  TData = unknown, 
  TVariables = unknown
> = (
  variables: TVariables
) => Promise<TData>;

There's not a lot of info in your question so I am filling in the blanks like this:

type Params = {
    something: string;
}

const api = async (args: {data: Params}): Promise<Response> => {
  return fetch('');
}

const setFriendCode = (data: Params) => api({ data })

You basically have two possible approaches here:

  1. You can set the generics on the useMutation hook and include some value for TError
const object = useMutation<Response, unknown, Params>(
  setFriendCode
)
  1. You can let the types be inferred and make sure that you have strong types for your arguments. With the types that I put on api and setFriendCode, I get <Response, unknown, Params, unknown>.
const object = useMutation(
  setFriendCode
)

useMutation does not return an array, instead it returns an object which contains several values to consume, check the following code:

const {
       data,
       error,
       isError,
       isIdle,
       isLoading,
       isPaused,
       isSuccess,
       mutate,
       mutateAsync,
       reset,
       status,
     } = useMutation(mutationFn, {
       mutationKey,
       onError,
       onMutate,
       onSettled,
       onSuccess,
       useErrorBoundary,
     })
     
Related