Javascript 流,对象文字与union不兼容

Javascript 流,对象文字与union不兼容,javascript,flowtype,Javascript,Flowtype,如果我有一个函数,它返回一个包含数据库信息的对象,或者一个空对象,如下所示: getThingFromDB: async function(id:string):Promise<EventObj|Empty>{ const fromDB = await dao.getEvent(id); if(fromDB && fromDB.length){ return fromDB[0]; } return {}; } 我错过

如果我有一个函数,它返回一个包含数据库信息的对象,或者一个空对象,如下所示:

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

}

我错过了什么?如何正确地满足这些错误。

可能的修补程序包括密封/冻结空的
对象。但这只是绕过了根本问题:您已经定义了一个精确的
对象
类型,尽管您只需要一个密封的类型:

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
您可以看到,只有空对象文本是流中未密封的
对象
类型。此时不需要精确的
对象
类型,您可以安全地从
{| |}
中删除精确的类型注释。那么它们有什么用处呢

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
使用精确的
对象
类型,您可以更好地控制宽度子类型


但是,宽度子类型也有其自身的缺陷,因为它会删除类型信息,正如您通过失败的属性访问
o.foo

尝试在函数体内部显式注释所看到的那样。我猜由于条件分支,流很难推断返回值的类型(尝试删除分支或冻结/密封对象文本
返回对象.freeze({});
对象.freeze({})成功了,谢谢!如果你把这个换成一个答案,我会认为它是正确的。
declare type EventObj = {
    id:string,
    name:string,
    urlName:string
};

declare type Empty = {||};
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
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