typescript - 将 firebase 链式方法重写为 promise.all

标签 typescript firebase google-cloud-functions

我创建了以下函数来删除用户,它是专用集合,效果很好。

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) {
    const userID = context.auth.uid;

    Auth.deleteUser(userID)
      .then(() => {
        UsersCollection.doc(userID).delete()
          .catch(error => {
            console.log(error)
          })
      })
      .catch(error => {
        console.log(error)
      })
  }
});

然后我尝试覆盖到 promise.all 中,这样用户的集合删除就不必等到用户实际删除。所以我尝试执行以下操作:

exports.deleteUser = functions.https.onCall((data, context) => {
  if (context.auth) {
    const userID = context.auth.uid;
    const promises = [];
    const deleteCollection = UsersCollection.doc(userID).delete();

    promises.push(Auth.deleteUser(userID));
    promises.push(deleteCollection);

    return Promise.all(promises)
  }
});

在这个魔法的构建过程中,控制台从 TSLint 输出以下错误:

src/index.ts:35:24 - error TS2769: No overload matches this call.
  The last overload gave the following error.
    Argument of type '(Promise<void> | Promise<WriteResult>)[]' is not assignable to parameter of type 'Iterable<void | PromiseLike<void>>'.
      Types of property '[Symbol.iterator]' are incompatible.
        Type '() => IterableIterator<Promise<void> | Promise<WriteResult>>' is not assignable to type '() => Iterator<void | PromiseLike<void>, any, undefined>'.
          Type 'IterableIterator<Promise<void> | Promise<WriteResult>>' is not assignable to type 'Iterator<void | PromiseLike<void>, any, undefined>'.
            Types of property 'next' are incompatible.
              Type '(...args: [] | [undefined]) => IteratorResult<Promise<void> | Promise<WriteResult>, any>' is not assignable to type '(...args: [] | [undefined]) => IteratorResult<void | PromiseLike<void>, any>'.
                Type 'IteratorResult<Promise<void> | Promise<WriteResult>, any>' is not assignable to type 'IteratorResult<void | PromiseLike<void>, any>'.
                  Type 'IteratorYieldResult<Promise<void> | Promise<WriteResult>>' is not assignable to type 'IteratorResult<void | PromiseLike<void>, any>'.
                    Type 'IteratorYieldResult<Promise<void> | Promise<WriteResult>>' is not assignable to type 'IteratorYieldResult<void | PromiseLike<void>>'.
                      Type 'Promise<void> | Promise<WriteResult>' is not assignable to type 'void | PromiseLike<void>'.
                        Type 'Promise<WriteResult>' is not assignable to type 'void | PromiseLike<void>'.
                          Type 'Promise<WriteResult>' is not assignable to type 'PromiseLike<void>'.
                            Types of property 'then' are incompatible.
                              Type '<TResult1 = WriteResult, TResult2 = never>(onfulfilled?: ((value: WriteResult) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined) => Promise<...>' is not assignable to type '<TResult1 = void, TResult2 = never>(onfulfilled?: ((value: void) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined) => PromiseLike<...>'.
                                Types of parameters 'onfulfilled' and 'onfulfilled' are incompatible.
                                  Types of parameters 'value' and 'value' are incompatible.
                                    Type 'WriteResult' is not assignable to type 'void'.

35     return Promise.all(promises)
                          ~~~~~~~~

  node_modules/typescript/lib/lib.es2015.iterable.d.ts:226:5
    226     all<TAll>(values: Iterable<TAll | PromiseLike<TAll>>): Promise<TAll[]>;
            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    The last overload is declared here.


Found 1 error.

据我所知,它不喜欢 promises.push(deleteCollection);,因为删除会消除 TSLint 问题。如果有人能阐明如何处理此类问题,我将不胜感激?

最佳答案

告诉 TypeScript promise 数组可以包含返回任何类型值的 promise :

const promises: Promise<any>[] = [];

此外,您可能必须告诉 TypeScript 您希望在所有代码路径中向客户端返回一个值:

if (context.auth) {
    // ...
    return Promise.all(promises)
}
else {
    return { error: "No authenticated user" }
}

请记住,对于可调用类型的函数,已解析的 promise 的值将被序列化并发送给客户端,因此您应该仔细考虑这是否是您真正想要发生的事情。

关于typescript - 将 firebase 链式方法重写为 promise.all,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57853260/

相关文章:

typescript - 如何使用带有参数和 Typescript 的 createSelector?

python - 使用 python 更新 Firebase 中的单个值

javascript - 如何更新html表中的firebase数据库数据?

python - 元数据中的启动脚本未运行(Python、谷歌计算引擎、云存储触发器)

firebase - 带有通配符路径的 Firestore 云功能触发器

javascript - 如何在 Cloud Functions for Firebase 中使用动态引用触发器

reactjs - 如何在 React 测试库中隔离测试?

node.js - Mongoose + TypeScript : Conditionally find() documents on model throws error: Union type has signatures, 但彼此不兼容

node.js - 将 Node.js 项目从纯 ES6 迁移到 TypeScript

twitter - 使用 Firebase 的 Twitter 应用程序中的错误回调 URL