You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义Hook中useQuery返回useQueryResults<unknown,unknown>类型问题

自定义Hook useGetQuery返回数据类型为unknown的解决方法

问题场景

我写了一个带页面聚焦重取功能的自定义Hook useGetQuery,代码如下:

type Props = Parameters<typeof useQuery>;

const useGetQuery = (...params: Props) => {
    const useQueryResults = useQuery(params);

    useFocusEffect(
        React.useCallback(() => {
            useQueryResults.refetch();
        }, [useQueryResults])
    );

    return useQueryResults;
};

接着在useGetScreen中调用这个Hook:

export const useGetScreen = (screenId: string) => {
    return useGetQuery(['getScreen', { screenId }], () => getScreen(screenId), { staleTime: 0 });
};

但调用const { data: screen } = useGetScreen('vegetables');时,screen的类型变成了unknown,而直接使用useQuery时TypeScript能自动推断类型。

问题原因

useQuery是泛型函数,它的返回类型依赖于传入的查询函数的返回值类型。但当前useGetQuery只是简单接收Parameters<typeof useQuery>作为参数,既没有保留useQuery的泛型信息,还错误地将参数数组直接传给useQuery(useQuery接收多个独立参数而非单个数组),双重原因导致TypeScript无法自动推导出返回数据的具体类型,只能默认设为unknown。

解决方案

让useGetQuery继承useQuery的泛型参数,并修正参数传递方式,确保类型信息能正确传递:

import { useQuery, QueryKey, UseQueryOptions, UseQueryResult } from '@tanstack/react-query';
import { useFocusEffect } from '@react-navigation/native';
import React from 'react';

const useGetQuery = <
  TQueryKey extends QueryKey,
  TQueryFnData = unknown,
  TError = unknown,
  TData = TQueryFnData,
  TContext = unknown
>(
  ...params: Parameters<typeof useQuery<TQueryKey, TQueryFnData, TError, TData, TContext>>
): UseQueryResult<TData, TError> => {
    const queryResult = useQuery(...params); // 展开参数,而非直接传数组

    useFocusEffect(
        React.useCallback(() => {
            queryResult.refetch();
        }, [queryResult])
    );

    return queryResult;
};

修改后,useGetScreen会自动继承getScreen(screenId)的返回类型,调用useGetScreen时screen就能获得正确的类型了。

简化版写法

如果不需要精细控制泛型参数,也可以用更简洁的方式复用useQuery的类型:

import { useQuery, UseQueryOptions, UseQueryResult } from '@tanstack/react-query';
import { useFocusEffect } from '@react-navigation/native';
import React from 'react';

const useGetQuery = <TData = unknown, TError = unknown>(
  queryKey: unknown[],
  queryFn: () => Promise<TData>,
  options?: Omit<UseQueryOptions<TData, TError>, 'queryKey' | 'queryFn'>
): UseQueryResult<TData, TError> => {
  const result = useQuery(queryKey, queryFn, options);

  useFocusEffect(
    React.useCallback(() => {
      result.refetch();
    }, [result])
  );

  return result;
};

内容的提问来源于stack exchange,提问作者Onyx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 17:20:44