Search code examples
async-awaites6-promiseflowtype

Flow does keeps interpreting variables as Promises after async/await


Reproduction :

// @flow
type A = { key: string, value: string};

const a:A = {
  key: 'a',
  value: 'a'
};

const foo = ():Promise<A> => {
    return new Promise(function(resolve, reject){
        setTimeout(function(){
            resolve(a);
        }, 1000);
    });
}

const bar = async ():A => {
    const res:A = ((await foo()):any);
    return res;
}

bar();

Try it on flow.org/try

Context :

When calling a function called 'foo' returning a promise with await, the type of the variable is still Promise.

Flow correctly interprets the value if we just return the variable, but triggers an error if we type the return of the function called 'bar'.

19:         return res;
                   ^ Cannot return `res` because property `key` is missing in `Promise` [1] but exists in `A` [2].
References:
[LIB] static/v0.75.0/flowlib/core.js:583: declare class Promise<+R> {
                                                        ^ [1]
17:     const bar = async ():A => {
                             ^ [2]

Solutions tried :

  • Forcing the type to 'A' of the variable calling await
  • Casting with any then 'A' didn't seem to solve the error.

Issues Related :

https://github.com/facebook/flow/issues/5294

Purpose of this question:

I am mostly looking for a workaround


Solution

  • This seems to be a simple misunderstanding, but the error message from Flow isn't very useful.

    You've declared bar as

    const bar = async (): A => {
    

    but async functions always return promises, so it should be

    const bar = async (): Promise<A> => {
    

    You can see it here on flow.org/try.