混合类型检查器函数,允许调用具有特定类型的函数



我基本上是在尝试创建"checker"函数,并根据该函数的结果调用另一个函数。此另一个函数只能接受单个类型。检查器功能应该"过滤"不需要的类型。

这里有一个例子:

class A {}
class B {}
const checkB = (entity: A | B): boolean => {
return (entity instanceof B)
}
const execute = (b: B) => {
console.log('executed')
}
const start = (entity: A | B) => {
if (checkB(entity)) {
execute(entity)
}
}
const a = new A()
const b = new B()
start(a)
start(b)

但是Flowtype不喜欢这样,并返回此错误:

execute(entity)
^ Cannot call `execute` with `entity` bound to `b` because `A` [1] is incompatible with `B` [2].
References:
15: const start = (entity: A | B) => {
^ [1]
11: const execute = (b: B) => {
^ [2]

我想知道是否有人能以某种方式说服flow以这种方式工作。流类型REPL链接:https://flow.org/try/#0PTAEAEDMBsHsHcBQiDG0CGBnToCCoBvAX2TSxwCFCTVYA7TAF1BQAsBTFAayoF5QAFOzqMAlowCeALjygAPqAoBKGQCNYsaO3R1QvAHyFEoUACd2jAK6ndQkeImhRDRjpTtYkRUsQ0U9JlB2AA9OS0Z2PUFVGWU9QwJjFgDNdgA6OABzAQByELCIgBMcnz8A5iZ0U2Z+OzFJGXwFOIMjE1EvATZOHjqHJSU2kyDQlHD2PskfExIyl1B0KLp2eDwBH3951SWVxXXkSuqBdB9DxgFVHyA

编辑:我的环境是用Flow v.0.72.0设置的,但正如您在REPL中看到的,它也不适用于0.86.0

2018年11月26日更新:

似乎有未记录的%checks注释将以这种方式工作:https://github.com/facebook/flow/issues/4723#issuecomment-325157852

// @flow
class A {}
class B {}
const checkB = (entity: A | B): boolean %checks => {
return (entity instanceof B)
}
const execute = (b: B) => {
console.log('executed')
}
const start = (entity: A | B) => {
if (checkB(entity)) {
execute(entity)
}
}
const a = new A()
const b = new B()
start(a)
start(b)

这不会再引发任何错误。然而,这也有一些问题:

如果checkB函数在不同的模块/文件中,则
  • 不起作用
  • 不适用于Flow的每个版本(是的,我使用较旧的Flow版本是因为一些原因,代码库相当大,目前无法快速更改以升级到较新的Flow版本(
  • 不适用于类方法(这实际上是我需要的(
  • 由于它没有记录在案,我对使用它有点怀疑,他们可能会稍后删除它,我会重新开始

看起来这是一个悬而未决的问题(也可以考虑添加您的案例:((。

然而,如果删除方法checkB并在start:中进行精确的细化,则效果良好

const start = (entity: A | B) => {
if (entity instanceof B) {
execute(entity)
}
}

如果您有更复杂的类型精化,并且需要将其提取到单独的方法中,则可以将checkB更改为getB,因为null精化似乎效果良好:

const getB = (entity: A | B): ?B => {
return (entity instanceof B) ? entity : null;
}
const execute = (b: B) => {
console.log('executed')
}
const start = (entity: A | B) => {
const b = getB(entity);
if (b) {
execute(b)
}
}

最新更新