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

React Query自定义请求类型校验报错:error为unknown的解决方法

解决React Query中error类型为unknown的TypeScript报错

你在使用TypeScript + React Query编写自定义请求函数时,访问locationQuery.error.message遇到TypeScript错误,提示'locationQuery.error' is of type 'unknown',对应的类型是QueryObserverRefetchErrorResult<IResponse, unknown> | QueryObserverLoadingErrorResult<IResponse, unknown>。

你的核心代码如下:

interface IResponse extends IGeolocation { /* ... 接口定义 */ }

export async function getLocation(searchTerm: string): Promise<IResponse> {
  const result = await geopuntApi.get(`/geolocation/location?q=${searchTerm}`);
  return result.data.LocationResult;
}

export function useLocation(searchTerm: string) {
  return useQuery<IResponse>(
    ['location', { searchTerm }],
    () => getLocation(searchTerm),
    { enabled: !!searchTerm },
  );
}

使用时的错误代码:

const locationQuery = useLocation(searchTerm);
{locationQuery.isError && <p>{locationQuery.error.message}</p>} // 此处报错

问题原因

React Query默认将错误类型设为unknown,因为它无法提前知晓你的请求会抛出何种类型的错误,这是TypeScript严格类型检查导致的报错。


解决方案

方案1:显式指定错误类型给useQuery

在useQuery的泛型参数中,第二个参数明确指定错误类型(比如通用的Error类型),这样React Query会将error的类型推断为你指定的类型:

export function useLocation(searchTerm: string) {
  console.log(`searchTerm binnen useLocation: ${searchTerm}`);
  // 泛型添加Error类型作为第二个参数
  return useQuery<IResponse, Error>(
    ['location', { searchTerm }],
    () => getLocation(searchTerm),
    {
      enabled: !!searchTerm,
    },
  );
}

修改后,locationQuery.error会被TypeScript识别为Error类型,直接访问.message就不会报错。

方案2:自定义错误类型并使用类型守卫(更安全)

如果你的API返回自定义格式的错误(比如包含message、statusCode等字段),可以先定义错误接口,再通过类型守卫缩小类型范围,确保类型安全:

  1. 定义自定义错误接口:
// 根据你的API实际返回的错误格式调整
interface ApiError {
  message: string;
  statusCode: number;
}
  1. 编写类型守卫函数:
function isApiError(error: unknown): error is ApiError {
  return (
    typeof error === 'object' &&
    error !== null &&
    'message' in error &&
    typeof (error as ApiError).message === 'string'
  );
}
  1. 使用时判断类型:
{locationQuery.isError && (
  <p>{isApiError(locationQuery.error) ? locationQuery.error.message : '请求失败,请稍后重试'}</p>
)}

这种方式避免了强制类型断言的不安全问题,同时能处理不同类型的错误情况。

方案3:临时强制类型断言(不推荐)

如果只是临时快速解决,也可以用类型断言直接指定错误类型,但这种方式跳过了TypeScript的类型检查,存在风险:

{locationQuery.isError && <p>{(locationQuery.error as Error).message}</p>}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 21:43:27