【问题标题】:Mobx Flow functions are not type checked by FlowType without .bind(this)没有 .bind(this) 的 FlowType 不会对 Mobx Flow 函数进行类型检查
【发布时间】:2019-03-14 00:16:37
【问题描述】:

当我们使用 MobX flow 修饰函数时,flowtype 认为 this 是 any 类型并且不进行类型检查。

class MyComponent extends Component<*> {
   actionMethod = flow(function*(){
        yield this.notAMethod();
   });
}

但是,如果我们将它绑定到生成器,flow 会理解 this 的类型是 MyComponent

 class MyComponent extends Component<*> {
       actionMethod = flow((function*(){
            yield this.notAMethod();
       }).bind(this));
    }

我的问题是我们如何确保这些方法经过类型检查。

  • 是否有任何 linting 规则来确保我们正确绑定(this)?
  • 我们可以改进 mobx 的分型吗?
  • 这是流量问题吗?

【问题讨论】:

    标签: javascript eslint flowtype mobx mobx-react


    【解决方案1】:

    您的问题简化为创建自定义 lint 的能力。 Eslint 有一个很棒的库来编写你自己的 eslint 规则。您可以使用https://astexplorer.net/ 进行比较,即使用和不使用this 的代码之间的差异。然后你可以编写一个看起来像这样的 eslint 规则(未经测试):

    // @no-flow
    "use strict";
    // Help from  https://astexplorer.net/
    module.exports.rules = {
      "mobx-flow-requires-bind": context => ({
        CallExpression: function(node) {
          const ancestors = context.getAncestors();
          const parent = ancestors.length > 0 && ancestors[ancestors.length - 1];
          if (node.callee && node.callee.name === "flow") {
            if (node.arguments.length === 1) {
              const callee = node.arguments[0].callee;
              if (!(callee && callee.property && callee.property.name === "bind")) {
                context.report(node, "Calls to flow must be used with .bind");
              }
            }
          }
        }
      })
    };
    

    您可以使用this 教程将上述代码集成到您的仓库中。

    【讨论】:

      【解决方案2】:

      这是我在研究中发现的一个建议。试一试,如果它解决了问题,请告诉我。基本上他们手动分配了 this 的类型。

      public fetchProjects = flow(function*(this: ProjectStore) {
          this.projects = yield ProjectApi.get()
      })
      

      【讨论】:

      • 谢谢,我相信这个语法只是打字稿。
      【解决方案3】:

      this 是在 javascript 中动态派生的。所以 flow 不能告诉你 this 将是什么类型的静态分析。唯一的例外是当您将它显式绑定到 this 时(就像您在第二种方法中所做的那样)或当您使用箭头函数时(但箭头函数不适用于 yield)。 考虑到这些知识,我将回答您的问题:

      是否有任何 linting 规则来确保我们正确绑定(this)?

      Flow 会告诉您使用绑定时的类型。所以你不需要 linting 规则,因为类型是正确的。

      我们可以改进 mobx 的类型吗?

      这不是 mobx 打字错误。这就是javascript的工作方式。您无法判断 this 在运行时将是什么类型(除非您使用绑定或箭头函数或调用对象实例的方法)

      这是流量的问题吗?

      见上面的答案。

      这是一篇关于 this 在 javascript 中如何工作的长文 https://stackoverflow.com/a/26574449/2379376

      希望我能帮助澄清您的问题。

      【讨论】:

      • 如果您删除对 flow 的调用,flowtype 确实知道 this 的类型。开发人员可能会忘记正确绑定 this,所以我想问题是你如何 lint 反对 this。
      猜你喜欢
      • 2020-07-13
      • 2017-12-16
      • 2017-08-05
      • 2018-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多