【问题标题】:Mixed types checker function to allow calling function with specific type混合类型检查器功能,允许调用具有特定类型的函数
【发布时间】:2018-11-26 22:39:29
【问题描述】:

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

这是一个例子:

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 以这种方式工作。 Flowtype 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 版本)
  • 不适用于类方法(这实际上是我需要的)
  • 由于没有记录,我对使用它有点怀疑,他们不妨稍后将其删除,然后我会重新开始

【问题讨论】:

    标签: javascript flowtype


    【解决方案1】:

    看起来是this opened issue(考虑也添加您的案例:))。

    但是,如果您删除方法 checkB 并在 start 中进行改进,则 works well

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

    如果您有更复杂的类型细化,需要将其提取到单独的方法中,可以将checkB更改为getB,如null refinements seems to works well

    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)
      }
    }
    

    【讨论】:

    • 我听到了,但是我上面发布的示例是我必须维护的大大简化的应用程序代码,不幸的是,这并不能以我想要/需要的方式解决问题。
    猜你喜欢
    • 2021-12-15
    • 1970-01-01
    • 2019-01-25
    • 2018-08-21
    • 1970-01-01
    • 2019-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多