没有.bind(this)的FlowType不会对Mobx Flow函数进行类型检查

时间:2018-10-09 09:08:48

标签: javascript eslint flowtype mobx mobx-react

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

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

但是,如果我们将其绑定到生成器,则流程将了解this的类型为MyComponent

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

我的问题是我们如何确保对这些方法进行类型检查。

  • 是否有任何起绒规则可确保我们正确绑定(此)?
  • 我们可以改善mobx的类型吗?
  • 这是流量问题吗?

3 个答案:

答案 0 :(得分:2)

是在javascript中动态派生的。因此流程无法告诉您静态分析 this 的类型。唯一的例外是当您将其显式绑定到此对象时(如您在第二种方法中所做的那样)或使用箭头函数(但箭头函数不适用于yield)。 考虑到这些知识,我将回答您的问题:

是否有任何整理规则可确保我们正确绑定(此)?

Flow告诉您使用绑定时的类型。因此,由于类型正确,因此您无需使用掉毛规则。

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

这不是mobx输入错误。这就是javascript的工作方式。您无法确定运行时 的类型(除非您使用bind或arrow函数或调用对象实例的方法)

这是流量问题吗?

请参阅上面的答案。

这是一篇有关javascript中 this 的工作方式的长篇文章 https://stackoverflow.com/a/26574449/2379376

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

答案 1 :(得分:2)

您的问题变成了创建自定义皮棉的能力。 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 :(得分:0)

这是我在研究中找到的建议。试试看,让我知道它是否解决了问题。基本上,他们是手动分配此类型的。

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