Reputation: 5562
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?
Upvotes: 4
Views: 14726
Reputation: 3878
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) => {
// ...
},
}
);
Upvotes: 1
Reputation: 43234
You can transform the response yourself:
export function postInviteTeamMember(payload: InviteMutationVars): Promise<User> {
return client.post('/user/invite/team', payload).then(response => response.data);
}
Upvotes: 2