Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React-query and Typescript - how to properly type a mutation result?

I have a simple hook that wraps the axios call in React Query:

function useInviteTeamMember(
  onSuccess?: Handler,
  onError?: Handler,
): UseMutationResult<User> {
  const mutation = useMutation(
    (payload: InviteMutationVars) => {
      return postInviteTeamMember(payload);
    },
    {
      onSuccess: (data) => {
    ...

The issue I have is that from the above definition you would expect the result to be of type User. Even in that onSuccess handler (data) is according to intellisense of type User. But it's not. To get the actual User object I have to do data['data'].

The actual post function is the root cause I think, since it types the Promise with :

export function postInviteTeamMember(payload: InviteMutationVars): Promise<User> {
  return client.post('/user/invite/team', payload);
}

So how can I rewrite this code so that the type of 'data' is correct?

like image 501
rmcsharry Avatar asked Sep 12 '25 13:09

rmcsharry


2 Answers

You can transform the response yourself:

export function postInviteTeamMember(payload: InviteMutationVars): Promise<User> {
  return client.post('/user/invite/team', payload).then(response => response.data);
}
like image 106
smac89 Avatar answered Sep 15 '25 03:09

smac89


If you type the return object in your mutation function, typescript will show that type on the onSuccess parameter.

Let's create a category as an example.

Here we have the mutation function, which we type the return as an object with key category and a value of type ExampleCategoryT. Typescript will know this function has a return type of : Promise< ExampleCategoryT>, so there is no need to explicitly write it (but you could if you wanted ofcourse).

export async function createCategory(category: CreateCategoryArg) {
  const { data } = await http.post<{ category: ExampleCategoryT }>(
    '/categories',
    { category }
  );

  return data.category;
}

In the useMutation function, the category argument will have a type of ExampleCategoryT.

const { mutate: createCategoryMutation } = useMutation(
  createCategory,
  {
    onSuccess: (category) => {
      queryClient.setQueryData<ExampleCategoryT[]>(
        ['categories'],
        (oldData = [) => [...oldData, category]
      );
   },
   onError: (error) => {
     // ...
    },
  }
);
like image 35
Tomas Vancoillie Avatar answered Sep 15 '25 02:09

Tomas Vancoillie