我有一个函数,它可以接受一个可处理的对象(一个具有then()方法的对象;请参阅Promise.resolve()的顶部)或其他一些东西:
function resolve<T>(value: {then: ()=>T}|T) {
if (value && value.then) {
console.log('thenable', value.then);
} else {
console.log('not thenable');
}
}当我在这个value.then语句中访问if时,Flow会发出抱怨。我可以用(value: any).then修复它,但这看起来很麻烦。
有人能推荐一种好的方法来检查这个吗?
发布于 2016-08-19 08:17:58
问得好!这是流动团队在过去几个星期里一直在努力解决的问题!
问题是什么?
if (value && value.then) {
// What is the type of `value` here?
} else在这个if语句中,value的类型是什么?如果T是string,那么它就是{then: ()=>T},正如您所期望的那样。但是如果T是{ then: string }呢?据我们所知,T可能有一个名为then的属性!
流程团队在做什么来解决这个问题?
value.then属性,并将value.then类型细化为mixed。很多这方面的工作已经掌握在大师手中了。您可以查看一下runs Type.org/try,它目前在主服务器上运行。您在Your .try/try上的示例
一旦这些东西登陆(有的在0.31.0版,有些在0.32.0版),我们将对其进行记录和博客。
编辑:添加更多信息
三个主要问题
有三个一般性问题,我们正在努力解决。
value.then?如果我们只在确定value.then具有then属性时才允许使用then,那么我们就可以捕获像value.tehn这样的排字。然而,惯用的JavaScript通常会测试对象中可能存在或可能不存在的属性。value的类型是什么。在提供的示例中,value是一个联合类型。value && value.then的目的似乎是检测该函数是否使用联合的左分支。但是,Flow不能安全地选择分支,因为T可能有一个then字段。value.then的类型是什么。同样,T可能是像{ then: string }这样的对象,所以value.then可能是任何东西。我们的解决方案
什么时候应该允许条件中的
value.then
我们将永远允许value.then。这意味着我们不能轻松地捕获属性名称输入,但这意味着我们可以支持更多的惯用JavaScript。Flow的主要原则之一是,它与人们倾向于编写的JavaScript很好地工作。
如果条件为true或false,
value的类型是什么。
如果Flow确实知道只有一个联合类型的分支能够工作,那么它将将value的类型细化到该分支。否则,value将不会被精炼。确切的类型将有助于这方面的工作。
如果条件为true或false,
value.then的类型是什么?
如果Flow确实知道只有一个联合类型的分支能够工作,那么它将将value.then类型细化为该分支上的then属性的类型。如果Flow确切地知道没有分支具有该属性,那么它将出错。否则,它将使用mixed类型。精确的类型也有助于这一点。
确切的类型是什么?
{ x: string }是具有属性x的对象的类型,该属性具有string类型。
var example1: { x: string } = { x: 'hello' }; // This is ok
var example2: { x: string } = { x: 'hello', y: 123 }; // This is also ok这对于惯用的JavaScript很有用,但是流很难说对象类型没有属性。所以我们加入了精确的类型。
{| x: string |}是具有属性x的对象的类型,该属性具有string类型,但没有其他属性。
var example1: {| x: string |} = { x: 'hello' }; // This is ok
var example2: {| x: string |} = { x: 'hello', y: 123 }; // Error! Extra property y!这很有帮助,因为您可以这样写:
type Foo = {| x: string |} | {| y: string |};
function test(arg: Foo): string | void {
if (arg.x) {
return arg.x;
}
}一旦我们发射了这些,我们就会记录下来!所以睁大你的眼睛!
https://stackoverflow.com/questions/39018508
复制相似问题