简体   繁体   English

流,对象文字与联合不兼容

[英]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: 我收到很多Flow错误,例如:

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. 可能的补丁包括密封/冻结空的Object文字。 But this only bypasses the underlying issue: You've defined an exact Object type though you only need a sealed one: 但这仅绕过了潜在的问题:尽管只需要密封的Object类型,但您已经定义了确切的Object类型:

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. 您可以看到流中只有空对象文字是未密封的Object类型。 Exact Object types are unnecessary at this point and you can safely remove the exact type annotation from {||} . 此时不需要精确的Object类型,您可以安全地从{||}删除确切的类型注释。 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. 使用精确的Object类型,您可以更好地控制宽度子类型。

However, width subtyping comes with its own pitfalls, because it erase type information as you can see by the failing property access o.foo . 但是,宽度子类型化有其自身的陷阱,因为宽度擦除会擦除类型信息,如失败的属性访问o.foo

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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