[英]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.