Reputation: 2427
I'm getting an error that 'The operand of an arithmetic operation must be a number.' but at the start of the function I have a runtime check to ensure that this.startedDateTime
is a number. I'm confused about why this type refinement doesn't work.
/* @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;
}
}
Upvotes: 1
Views: 262
Reputation:
The problem is that type refinements are invalidated with the first subsequent function call - Date().getTime()
in your example.
Functions/methods aren't pure in Javascript but may perform side effects. Date().getTime()
for example may delete this.startedDateTime
or set it to null
. Consequently flow invalidates your refinement to preserve type safety.
To bypass this behavior you can store the property in a constant before any function invocation:
/* @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;
}
}
Upvotes: 3
Reputation: 2394
In your approach startedDateTime
can be: number
, null
or undefined
, because you are using Flow Maybe Types. You just need to say: startedDateTime: number;
.
Here you are a example.
Maybe you want to do this:
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;
}
}
Upvotes: 1