React Redux Query中Property 'csrf_token'类型不存在错误求解
解决Redux Toolkit Query中
Property 'csrf_token' does not exist on type '{}'错误 问题原因
TypeScript无法推断refreshResult.data的具体结构,默认将其识别为unknown或空对象类型,因此无法识别csrf_token属性。
解决方案
1. 定义刷新接口返回类型
先创建一个TypeScript接口,明确/user/refreshToken接口的返回数据结构:
interface RefreshTokenResponse { csrf_token: string; }
2. 给refreshResult添加类型断言
在调用baseQuery获取刷新结果后,对返回数据做类型断言,告知TypeScript它符合我们定义的接口结构:
修改获取刷新token的代码段:
const refreshResult = await baseQuery( {url:'/user/refreshToken', method:"POST"}, api, extraOptions ) as { data: RefreshTokenResponse }; // 添加类型断言 if (refreshResult?.data) { api.dispatch(setToken(refreshResult.data.csrf_token)); result = await baseQuery(args, api, extraOptions); }
3. (可选)优化泛型定义(进阶)
如果希望类型约束更严谨,可以调整baseQueryWithReauth的泛型参数,加入刷新接口的返回类型:
const baseQueryWithReauth: BaseQueryFn< string | FetchArgs, unknown | RefreshTokenResponse, // 加入刷新返回类型 FetchBaseQueryError > = async (args, api, extraOptions) => { // 原有代码逻辑 }
修改后的完整代码示例
import { setLoggedout, setToken } from '@/features/auth'; import { BaseQueryFn, FetchArgs, FetchBaseQueryError, createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; import type { RootState } from '@/store' const baseURL = import.meta.env.VITE_BACKEND_URL // 定义刷新token接口的返回类型 interface RefreshTokenResponse { csrf_token: string; } const baseQuery = fetchBaseQuery({ baseUrl: baseURL, credentials: "include", prepareHeaders: (headers, {getState}) =>{ const token = (getState() as RootState).userAuth.token if(token){ headers.set('X-XSRF-TOKEN',token); } return headers; } }) const baseQueryWithReauth: BaseQueryFn< string | FetchArgs, unknown, FetchBaseQueryError > = async (args, api, extraOptions) => { let result = await baseQuery(args, api, extraOptions); if (result?.error?.status === 403) { console.log("Sending refreshtoken"); // 给refreshResult添加类型断言 const refreshResult = await baseQuery( {url:'/user/refreshToken', method:"POST"}, api, extraOptions ) as { data: RefreshTokenResponse }; if (refreshResult?.data) { api.dispatch(setToken(refreshResult.data.csrf_token)); result = await baseQuery(args, api, extraOptions); } else { api.dispatch(setLoggedout()); } } return result; } export const apiSlice = createApi({ baseQuery: baseQueryWithReauth, tagTypes: ['Auth', 'User'], endpoints: () => ({}) });
内容的提问来源于stack exchange,提问作者wk98
相关产品推荐
相关产品推荐

