在Flow中键入Refinements

时间:2017-10-31 13:45:16

标签: javascript reactjs flowtype

我收到的错误是'算术运算的操作数必须是数字'。但是在函数的开头我有一个运行时检查,以确保this.startedDateTime是一个数字。我很困惑为什么这种类型的改进不起作用。

/* @flow */

class Transfer {
    startedDateTime: ?number;

    start() {
        this.startedDateTime = new Date().getTime();
    }

    get elapsedTime(): ?number {
        if (typeof this.startedDateTime === 'number') {
            const currentDateTime: number = new Date().getTime();
            const elapsedMs: number = this.startedDateTime - currentDateTime;
            return elapsedMs;
        }
        return null;
    }
}

Try it here

2 个答案:

答案 0 :(得分:3)

问题是类型细化在第一个后续函数调用中无效 - 在您的示例中为Date().getTime()

函数/方法在Javascript中不纯,但可能会执行副作用。例如Date().getTime()可能会删除this.startedDateTime或将其设置为null。因此,流程会使您的细化无效,以保持类型安全。

要绕过此行为,您可以在任何函数调用之前将该属性存储在常量中:

/* @flow */

class Transfer {
  startedDateTime: ?number;

  start() {
    this.startedDateTime = new Date().getTime();
  }

  get elapsedTime(): ?number {
    if (typeof this.startedDateTime === 'number') {
      const startedDateTime = this.startedDateTime;
  //  ^^^^^^^^^^^^^^^^^^^^^
      const currentDateTime: number = new Date().getTime();
      const elapsedMs: number = startedDateTime - currentDateTime;
  //                            ^^^^^^^^^^^^^^^
      return elapsedMs;
    }
    return null;
  }
}

Try it

答案 1 :(得分:1)

您的方法startedDateTime可以是:numbernullundefined,因为您使用的是Flow Maybe Types。您只需要说:startedDateTime: number;

此处您是example

也许你想这样做:

class Transfer {
    startedDateTime: ?number;
    start() {
        return this.startedDateTime = new Date().getTime();
    }
    get elapsedTime(): ?number {
        if (typeof this.startedDateTime === 'number') {
            const currentDateTime: number = new Date().getTime();
            const elapsedMs: number = this.start() - currentDateTime;
            return elapsedMs;
        }
        return null;
    }
}