Marcus Junius Brutus - 4 months ago 9

Javascript Question

I have the following code using Flow:

`// @flow`

'use strict';

import assert from 'assert';

declare interface IPoint {

x: number;

y: number;

distanceTo(other: IPoint): number;

}

class Point {

x: number;

y: number;

distanceTo(a: IPoint): number {

return distance(this, a);

}

constructor(x: number, y: number) {

this.x = x;

this.y = y;

}

}

function distance(p1: IPoint, p2: IPoint): number {

function sq(x: number): number {

return x*x;

}

return Math.sqrt( sq(p2.x-p1.x)+sq(p2.y-p1.y) );

}

assert(distance ( new Point(0,0), new Point(3,4))===5);

// distance ( new Point(3,3), 3); // Flow complains, as expected

assert((new Point(0,1)).distanceTo(new Point(3,5))===5);

// (new Point(0,1)).distanceTo(3); // Flow complains as expected

Running

`npm run flow`

So all's well with the world except that I don't know how to make it explicit at the point where class

`Point`

`IPoint`

Answer

Here is the simplest way to do it:

```
class Point {
x: number;
y: number;
constructor(x: number, y: number) {
(this: IPoint);
this.x = x;
this.y = y;
}
}
```

The key part is `(this: IPoint)`

. From JS VM's point of view it's just an expression that does nothing, but Flow needs to check if casting `this`

to `IPoint`

is valid, effectively checking if class implements `IPoint`

interface.