2017-09-22 49 views
1

如果我有一个返回值或者从数据库或信息的空对象这样的对象的功能:流程,对象与工会文字不兼容

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

} 

我得到了很多像流的错误:

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

或者

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

这里是我的声明的对象类型。

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

declare type Empty = {||}; 

我在想什么?我如何正确地解决这些错误。

+1

尝试在函数体内显式注释。我想流具有麻烦推断类型的返回值的由于条件分支(尝试删除分支或冷冻/密封对象常量'返回Object.freeze({});') – ftor

+0

'Object.freeze({ });'做了诡计,谢谢!如果你改变这个答案,我会接受它作为正确的答案。 – Newtang

回答

1

一个可能的补片由密封/冷冻空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 

你可以看到,只有空对象字面是不密封的Object类型的流量。在这一点上,确切的Object类型是不必要的,您可以安全地从{||}中删除确切的类型注释。那么它们有什么用处?

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 

有了确切Object类型,你有超过宽度亚型更好的控制。

然而,宽子类型都有自己的缺陷,因为它抹去类型的信息,你可以通过失败的属性访问o.foo看到。