How to use Promise.all() with Typescript

前端 未结 6 2038
旧时难觅i
旧时难觅i 2020-12-08 18:27

Here is what I want to do:

Promise.all([aurelia.start(), entityManagerProvider.initialize()])
    .then((results:Array) => {
        let aureli         


        
相关标签:
6条回答
  • 2020-12-08 18:40

    I have the same issue with you, but with this code, all work perfectly.

    type TList = Promise<Aurelia> | Promise<void>;
    
    const foo: TList[] = [aurelia.start(), entityManagerProvider.initialize()];
    
    Promise.all<TList>(foo).then((results) => {
        let aurelia = results[0];
        aurelia.setRoot();
    });
    
    0 讨论(0)
  • 2020-12-08 18:45

    Since Promise::all is a generic function, you can declare the return types of each promise like this:

    Promise.all<Aurelia, void>([
      aurelia.start(),
      entityManagerProvider.initialize()
    ])
    .then(([aurelia]) => aurelia.setRoot());
    
    0 讨论(0)
  • 2020-12-08 18:46

    I somehow landed here when I was looking for return type of Promise.all() since straightforward [Promise<any>, Promise<any>] is obviously not working.

    Eventually it turned out to be simplier than it seems:

    const severalMongoDbOperations: Promise<[DeleteWriteOpResultObject, UpdateWriteOpResult]> =
      () => Promise.all([
        mongo.deleteOne({ ... }),
        mongo.updateOne({ ... })
      ]);
    

    Later it can be used with .then() or:

    try {
      const ops: [DeleteWriteOpResultObject, UpdateWriteOpResult] = await severalMongoDbOperations();
    } catch (e) {
      // Process rejection
    }
    
    0 讨论(0)
  • 2020-12-08 18:49

    This is a weakness in the TypeScript and its Promise.all signature. Its generally best to have arrays with consistent types. You can do the following manually though:

    let foo : [Promise<Aurelia>,Promise<void>] = [aurelia.start(), entityManagerProvider.initialize()];
    Promise.all(foo).then((results:any[]) => {
        let aurelia: any = results[0];
        aurelia.setRoot();
    });
    
    0 讨论(0)
  • 2020-12-08 18:53

    At least from TypeScript 2.7.1 onwards, the compiler seems to resolve the types without help, with a syntax like this:

    Promise.all([fooPromise, barPromise]).then(([foo, bar]) => {
      // compiler correctly warns if someField not found from foo's type
      console.log(foo.someField);
    });
    

    Hat tip: @JamieBirch (from comment to @AndrewKirkegaard's answer)

    0 讨论(0)
  • 2020-12-08 18:58

    If you'd like to keep type-safety, it's possible to extend the native type-definition of the Promise object (of type PromiseConstructor) with additional overload signatures for when Promise.all is called with a finite number of not-necessarily inter-assignable values:

    interface PromiseConstructor
    {
        all<T1, T2>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>]): Promise<[T1, T2]>;
        all<T1, T2, T3>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>]): Promise<[T1, T2, T3]>;
        ...
    }
    

    Add as many overloads as you need. This approach provides full type-safety for all elements in the value argument of the onfulfilled callback:

    Promise.all([1, "string", true]).then(value =>
    {
        let a: number = value[0]; // OK
        let b: number = value[1]; // Type 'string' is not assignable to type 'number'.
        ...
    });
    
    0 讨论(0)
提交回复
热议问题