将Firebase链式方法改写为Promise.all时遇TypeScript类型错误求解
解决TypeScript中Promise.all的类型不兼容问题
你遇到的这个TypeScript错误,核心原因是Promise.all对传入的Promise数组有类型一致性要求:Auth.deleteUser(userID)返回的是Promise<void>,而UsersCollection.doc(userID).delete()返回的是Promise<WriteResult>,这两个Promise的resolved值类型不兼容,导致TypeScript无法推导出统一的泛型类型,从而抛出TS2769错误。
下面给你两种可行的解决方案,同时还会优化一些原代码里的潜在问题:
方案一:将WriteResult类型的Promise转为void类型
通过.then(() => {})忽略delete()方法返回的WriteResult,让这个Promise的resolved值变为void,和deleteUser()的Promise类型保持一致:
import * as admin from 'firebase-admin'; import * as functions from 'firebase-functions'; admin.initializeApp(); const Auth = admin.auth(); const UsersCollection = admin.firestore().collection(`users`); exports.deleteUser = functions.https.onCall((data, context) => { // 处理未认证的情况,抛出标准的HttpsError if (!context.auth) { throw new functions.https.HttpsError( 'unauthenticated', '必须先登录才能执行此操作' ); } const userID = context.auth.uid; const promises = [ Auth.deleteUser(userID), // 忽略WriteResult,转为Promise<void> UsersCollection.doc(userID).delete().then(() => {}) ]; return Promise.all(promises) .then(() => ({ success: true, message: '用户及数据已成功删除' })) .catch(error => { // 抛出标准错误,让客户端能捕获到具体问题 throw new functions.https.HttpsError( 'internal', '删除操作失败', error.message ); }); });
方案二:显式指定Promise.all的泛型类型
直接告诉TypeScript我们接受void或WriteResult类型的Promise数组,这样就能绕过自动类型推导的限制:
import * as admin from 'firebase-admin'; import * as functions from 'firebase-functions'; admin.initializeApp(); const Auth = admin.auth(); const UsersCollection = admin.firestore().collection(`users`); exports.deleteUser = functions.https.onCall((data, context) => { if (!context.auth) { throw new functions.https.HttpsError( 'unauthenticated', '必须先登录才能执行此操作' ); } const userID = context.auth.uid; const promises = [ Auth.deleteUser(userID), UsersCollection.doc(userID).delete() ]; // 显式指定泛型类型为void | WriteResult return Promise.all<void | admin.firestore.WriteResult>(promises) .then(() => ({ success: true, message: '用户及数据已成功删除' })) .catch(error => { throw new functions.https.HttpsError( 'internal', '删除操作失败', error.message ); }); });
额外优化说明
- 未认证处理:原代码中如果
context.auth为null(用户未登录),函数会直接返回undefined,这不符合云函数的规范,应该抛出functions.https.HttpsError,让客户端能正确处理未认证的情况。 - 错误处理:原代码没有捕获
Promise.all的错误,云函数需要返回一个完整的Promise链,并且在出错时抛出标准错误,避免函数超时或静默失败。
内容的提问来源于stack exchange,提问作者volna
相关产品推荐
相关产品推荐

