如何解决TypeScript中'loginError.data'类型为'unknown'的报错?
解决RTK Query中useLoginMutation的error.data类型未知问题
问题分析
你遇到的报错核心原因是:FetchBaseQueryError的data字段本身类型为unknown——RTK Query无法提前预知服务器返回的错误数据结构,所以即便通过类型守卫确认了error是FetchBaseQueryError,data的类型依然需要进一步收窄,才能安全访问message属性。
解决方案1:添加额外类型守卫收窄data类型
先定义检查错误数据结构的类型守卫,再结合原有守卫使用:
import { FetchBaseQueryError } from "@reduxjs/toolkit/dist/query"; // 定义预期的错误响应结构 interface ApiErrorData { message: string; } // 检查error是否为FetchBaseQueryError export function isFetchBaseQueryError(error: unknown): error is FetchBaseQueryError { return typeof error === "object" && error != null && "status" in error; } // 检查data是否包含message字段 export function isApiErrorData(data: unknown): data is ApiErrorData { return typeof data === "object" && data != null && "message" in data; }
在组件中使用:
if (!isLoginLoading && error) { if (isFetchBaseQueryError(error)) { // 先判断data存在且符合预期结构 if (error.data && isApiErrorData(error.data)) { notification.error({ message: "Login Failed", description: error.data.message, }); } else { // 处理其他错误情况,比如data是字符串或无数据 notification.error({ message: "Login Failed", description: typeof error.data === "string" ? error.data : "Unknown error occurred", }); } } else { // 处理非RTK Query的错误 notification.error({ message: "Login Failed", description: String(error), }); } }
解决方案2:在API Slice中指定错误类型
通过transformErrorResponse配置,让RTK Query自动推断错误数据类型,减少类型守卫的使用:
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; // 定义登录请求参数类型 interface LoginParams { username: string; password: string; } // 定义登录成功响应类型 interface LoginSuccessResponse { token: string; userInfo: { id: number; name: string }; } // 定义服务器返回的错误响应类型 interface LoginErrorResponse { message: string; } export const authApi = createApi({ reducerPath: 'authApi', baseQuery: fetchBaseQuery({ baseUrl: '/api/auth' }), endpoints: (builder) => ({ login: builder.mutation<LoginSuccessResponse, LoginParams>({ query: (params) => ({ url: '/login', method: 'POST', body: params, }), // 转换错误响应,指定错误数据类型 transformErrorResponse: (response) => response.data as LoginErrorResponse, }), }), }); export const { useLoginMutation } = authApi;
此时useLoginMutation返回的error对象中,data的类型会被推断为LoginErrorResponse,可直接访问error.data.message(仍需判断error是否存在):
if (!isLoginLoading && error) { notification.error({ message: "Login Failed", description: error.data.message, }); }
内容的提问来源于stack exchange,提问作者BLIND
相关产品推荐
相关产品推荐

