Firebase+RTK Query中queryFn的TypeScript类型错误求助
解决RTK Query结合Firebase Mutation的TypeScript类型错误
问题根源分析
你遇到的类型错误主要来自两个方面:
- 泛型参数不匹配:你给
builder.mutation指定的第一个泛型是void,但实际queryFn返回了包含docRef和success的结构化数据,类型冲突。 - 错误类型不符合要求:RTK Query要求
queryFn返回的error必须是可序列化的标准结构,直接返回原始Error对象会导致类型不兼容。
修复步骤
1. 定义明确的类型(可选但推荐)
先为请求参数、返回数据和错误定义TypeScript类型,让类型检查更严格:
// 假设你的AddTransactionArgs已经定义,这里补充返回和错误类型 type AddTransactionResponse = { docRef: DocumentReference<DocumentData>; success: boolean; }; type AddTransactionError = { message: string; };
2. 修正Mutation泛型与返回值
调整builder.mutation的泛型参数,确保返回的data和error类型匹配:
export const transactionsApi = createApi({ reducerPath: 'transactionsApi', baseQuery: fakeBaseQuery(), tagTypes: ['Transactions'], endpoints: (builder) => ({ addTransaction: builder.mutation<AddTransactionResponse, AddTransactionArgs>({ queryFn: async (args) => { const transactionCollectionRef = collection(db, 'transactions'); try { const docRef = await addDoc(transactionCollectionRef, { ...args, createdAt: serverTimestamp() }); // 返回符合定义的data结构 return { data: { docRef, success: true } }; } catch (err) { console.error(err); // 将原始错误转换为RTK Query兼容的结构 const error = err as Error; return { error: { message: error.message } }; } }, // 可选:添加缓存标签失效,自动更新相关数据 invalidatesTags: ['Transactions'] }) }) });
如果你不需要返回数据(只想返回void)
如果你的业务场景不需要返回docRef等数据,只需标记操作成功,可将泛型改为void,并返回data: undefined:
addTransaction: builder.mutation<void, AddTransactionArgs>({ queryFn: async (args) => { const transactionCollectionRef = collection(db, 'transactions'); try { await addDoc(transactionCollectionRef, { ...args, createdAt: serverTimestamp() }); // 对应void类型,返回undefined return { data: undefined }; } catch (err) { console.error(err); const error = err as Error; return { error: { message: error.message } }; } }, invalidatesTags: ['Transactions'] })
关键注意点
- RTK Query的
queryFn返回值必须严格符合QueryReturnValue<TData, TError>结构,即要么返回{ data: TData },要么返回{ error: TError }。 - 错误对象必须是可序列化的(不能直接返回原生
Error实例),通常转换为包含message字段的简单对象即可。
内容的提问来源于stack exchange,提问作者Tomas Gil Amoedo
相关产品推荐
相关产品推荐

