我有一个函数接受 thenable(具有 then()
方法的对象;参见 MDN JavaScript docs: Promise.resolve()
的顶部)或其他:
function resolve<T>(value: {then: ()=>T}|T) {
if (value && value.then) {
console.log('thenable', value.then);
} else {
console.log('not thenable');
}
}
当我在此 if
语句中访问 value.then
时,Flow 会报错。我可以用 (value: any).then
修复它,但这看起来很老套。
谁能推荐一种类型检查的好方法?
最佳答案
好问题!这是 Flow 团队在过去几周一直在努力解决的问题!
问题是什么
if (value && value.then) {
// What is the type of `value` here?
} else
在 if 语句中,value
的类型是什么?如果 T
是 string
,那么它将是 {then: ()=>T}
,如您所料。但是如果 T
是 { then: string }
呢?据我们所知,T
可能有一个名为 then
的属性!
Flow 团队正在做什么来解决这个问题?
- 添加确切的对象类型。这个问题来自不知道工会的一个分支是否可能拥有属性(property)。使用确切的类型,您可以准确地告诉 Flow 一个对象具有哪些属性。
- 允许
value.then
属性检查,并将value.then
的类型细化为mixed
。
其中很多工作已经在 master 中了。您可以查看 flowtype.org/try,它目前由 master 运行。 Your example on flowtype.org/try
一旦这些东西落地(一些出现在 v0.31.0 中,一些出现在 v0.32.0 中),我们将对其进行记录和博客。
编辑:添加更多信息
3个主要问题
我们正在努力解决 3 个一般性问题。
- 我们什么时候应该在条件语句中允许
value.then
?如果我们只允许value.then
当我们确定value
有一个then
属性时,那么我们可以捕获像value 这样的拼写错误.tehn
。但是,惯用的 JavaScript 经常测试对象中可能存在或不存在的属性。 - 如果条件为真或假,
值
的类型是什么。在提供的示例中,value
是联合类型。看起来value && value.then
的目的是检测函数是否正在使用联合的左分支。然而,Flow 不能安全地选择一个分支,因为 T 可能有一个then
字段。 - 如果条件为真或假,
value.then
的类型是什么。同样,T
可能是一个像{ then: string }
这样的对象,所以value.then
可能是任何东西
我们的解决方案
When should we allow
value.then
in a conditional
我们将始终允许 value.then
。这意味着我们不能轻易捕获属性名称拼写错误,但这意味着我们可以支持更多地道的 JavaScript。 Flow 的主要原则之一是它可以很好地与人们倾向于编写的 JavaScript 配合使用。
What is the type of
value
if the conditional is true or false.
如果 Flow 确定联合类型中只有一个分支可以工作,它会将 value
的类型细化到该分支。否则,value
将不会被细化。精确类型将对此有所帮助
What is the type of
value.then
if the conditional is true or false
如果 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 很有用,但让 Flow 很难说一个对象类型没有属性。所以我们要添加精确类型。
{| 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;
}
}
一旦我们推出这些,我们将记录它们!所以请擦亮眼睛!
关于javascript - 流: check type of thenable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39018508/