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

将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
      );
    });
});

额外优化说明

  1. 未认证处理:原代码中如果context.auth为null(用户未登录),函数会直接返回undefined,这不符合云函数的规范,应该抛出functions.https.HttpsError,让客户端能正确处理未认证的情况。
  2. 错误处理:原代码没有捕获Promise.all的错误,云函数需要返回一个完整的Promise链,并且在出错时抛出标准错误,避免函数超时或静默失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:56:51