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

React Query中'isSuccess'属性类型不兼容问题排查与解决

React Query UseQueryResult 与自定义 QueryResult 类型不兼容问题

错误原因

核心问题是自定义的QueryResult联合类型未覆盖UseQueryResult的全部状态分支:

  • React Query 的UseQueryResult包含多组状态组合:初始加载(isPending: true)、加载成功(isSuccess: true)、加载失败(isError: true),以及重新获取数据时的混合状态(如isSuccess: true同时isPending: true)。
  • 你的QueryResult仅定义了两种状态:加载中(isPending: true+isSuccess: false)、加载成功(isSuccess: true+isPending: false),完全遗漏了错误状态(isError: true)及其他合法状态组合。
  • TypeScript 检测到UseQueryResult中存在QueryObserverRefetchErrorResult这类分支(比如重新获取失败时,isSuccess: false但isPending: false、isError: true),无法匹配QueryResult的任何分支,因此抛出isSuccess类型不兼容的错误。

解决方法

由于架构限制无法直接使用UseQueryResult,你需要扩展自定义QueryResult覆盖所有必要状态,或通过适配函数将UseQueryResult安全转换为QueryResult类型。

方法1:完善QueryResult类型,覆盖全状态分支

修改QueryResult,添加错误状态和重新加载的混合状态分支,对齐UseQueryResult的状态覆盖范围:

import { get } from "lodash-es"
import { useQuery } from '@tanstack/react-query'

// 扩展QueryResult,覆盖错误状态与重新加载状态
type QueryResult<TData extends object> =
    | {
          isSuccess: false
          isPending: true
          isError: false
          data: undefined
      }
    | {
          isSuccess: true
          isPending: false
          isError: false
          data: TData
      }
    | {
          isSuccess: true
          isPending: true
          isError: false
          data: TData
      }
    | {
          isSuccess: false
          isPending: false
          isError: true
          data: undefined
          error: Error
      }

class DataListManager<TData extends object, TPath extends keyof TData> {
    constructor(
        private readonly _query: QueryResult<TData>,
        private readonly _path: TPath,
    ) {}

    get query() {
        const items = get(this._query.data, this._path) ?? []

        return {
            ...this._query,
            data: {
                items,
            },
        }
    }
}

type Transaction = {}

function useTransactionsListManager() {
    const query = useQuery({
        async queryFn() {
            const data = await new Promise<{transactions: Array<Transaction>}>(resolve => {
                resolve({ transactions: [] })
            })
            return data
        },
        queryKey: ['transactions']
    })

    // 类型匹配,无报错
    return new DataListManager(query as QueryResult<{ transactions: Transaction[] }>, "transactions")
}

方法2:创建适配函数,安全转换类型

若不想修改QueryResult结构,可编写适配函数将UseQueryResult的状态映射到自定义QueryResult分支:

import { get } from "lodash-es"
import { useQuery, UseQueryResult } from '@tanstack/react-query'

type QueryResult<TData extends object> =
    | {
          isSuccess: false
          isPending: true
          isError: false
          data: undefined
      }
    | {
          isSuccess: true
          isPending: false
          isError: false
          data: TData
      }

// 适配函数:将UseQueryResult转换为QueryResult
function adaptToQueryResult<TData extends object>(
  query: UseQueryResult<TData, Error>
): QueryResult<TData> {
  if (query.isSuccess && !query.isPending) {
    return {
      isSuccess: true,
      isPending: false,
      isError: false,
      data: query.data,
    }
  }
  if (query.isPending && !query.isError) {
    return {
      isSuccess: false,
      isPending: true,
      isError: false,
      data: undefined,
    }
  }
  // 错误状态可根据业务需求映射为兼容分支,此处示例映射为非成功非加载状态
  return {
    isSuccess: false,
    isPending: false,
    isError: false,
    data: undefined,
  }
}

class DataListManager<TData extends object, TPath extends keyof TData> {
    constructor(
        private readonly _query: QueryResult<TData>,
        private readonly _path: TPath,
    ) {}

    get query() {
        const items = get(this._query.data, this._path) ?? []

        return {
            ...this._query,
            data: {
                items,
            },
        }
    }
}

type Transaction = {}

function useTransactionsListManager() {
    const query = useQuery({
        async queryFn() {
            const data = await new Promise<{transactions: Array<Transaction>}>(resolve => {
                resolve({ transactions: [] })
            })
            return data
        },
        queryKey: ['transactions']
    })

    // 使用适配函数转换类型
    return new DataListManager(adaptToQueryResult(query), "transactions")
}

关键说明

  • 若业务需处理错误状态,优先选择方法1扩展QueryResult,能更准确映射所有状态。
  • 方法2的适配函数需根据实际业务逻辑处理错误状态的映射,确保转换后类型符合QueryResult定义。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 16:30:05