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.