React-query 和 Typescript - 如何正确输入突变结果?

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

我有一个简单的钩子,可以在 React Query 中包装 axios 调用:

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

我遇到的问题是,根据上面的定义,您会期望结果是 User 类型。 即使在那个 onSuccess 处理程序(数据)中也是根据用户类型的智能感知。 但事实并非如此。 要获得实际的用户对象,我必须执行数据['data'].

实际的 post 函数是我认为的根本原因,因为它用 :

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

那么我该如何重写这段代码才能使 'data' 的类型正确?

您可以自己转换响应:

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

如果您在突变函数中键入 return 对象,打字稿将在 onSuccess 参数上显示该类型。

我们以创建一个类别为例。

这里我们有变异函数,我们将 return 键入为一个对象,键为 category,值类型为 ExampleCategoryT。 Typescript 会知道此函数的 return 类型为 : Promise< ExampleCategoryT>,因此无需显式编写它(但如果您愿意,当然可以)。

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

  return data.category;
}

在 useMutation 函数中,category 参数的类型为 ExampleCategoryT

const { mutate: createCategoryMutation } = useMutation(
  createCategory,
  {
    onSuccess: (category) => {
      queryClient.setQueryData<ExampleCategoryT[]>(
        ['categories'],
        (oldData = [) => [...oldData, category]
      );
   },
   onError: (error) => {
     // ...
    },
  }
);