重写firebase链式方法以保证promise.all

时间:2019-09-09 11:37:45

标签: 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问题。如果有人可以澄清如何处理此类问题,我将不胜感激。

1 个答案:

答案 0 :(得分:3)

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

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

您还可能必须告诉TypeScript您希望在所有代码路径中将值返回给客户端:

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

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