简体   繁体   中英

Flow, object literal incompatible with union

If I have a function that returns either an object with information from the database or an empty object like this:

getThingFromDB: async function(id:string):Promise<EventObj|Empty>{
    const fromDB = await dao.getEvent(id);
    if(fromDB && fromDB.length){
        return fromDB[0];
    }
    return {};

}

I get a lot of Flow errors like:

return {};
       ^^ object literal. This type is incompatible with
getThingFromDB: async function(id:string):Promise<EventObj|Empty>{                                                                                
                                                  ^^^^^^^^^^^^^^ union: EventObj | Empty

Or

getThingFromDB: async function(id:string):Promise<EventObj|Empty>                                                                                      
                                                  ^^^^^^^^ property `id`. Property not found in
return {};
       ^^ object literal

Here are my declared object types.

declare type EventObj = {
    id:string,
    name:string,
    urlName:string
};

declare type Empty = {||};

What am I missing? How do I properly satisfy these errors.

A possible patch consists of sealing/freezing the empty Object literal. But this only bypasses the underlying issue: You've defined an exact Object type though you only need a sealed one:

type Empty = {};

let o = {};
let p = {foo: true};
let q: Empty = {};

o.foo = true; // type checks
p.bar = true; // type error
q.foo = true; // type error

You can see that only the empty object literal is an unsealed Object type in flow. Exact Object types are unnecessary at this point and you can safely remove the exact type annotation from {||} . What are they useful for then?

type Foo = {|foo: boolean|};
type Bar = {bar: boolean};

const f = (o: Foo) => o;
const g = (o: Bar) => o;

f({foo: true, bar: true}); // type error
let o = g({foo: true, bar: true}); // type checks

o.foo; // type error

With exact Object types you have a finer control over width subtyping.

However, width subtyping comes with its own pitfalls, because it erase type information as you can see by the failing property access o.foo .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM