如何声明给定的 class 实现了 Facebook Flow 中的接口?
how to declare that a given class implements an interface in Facebook Flow?
我有以下使用 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
运行 npm run flow
不会像预期的那样产生任何抱怨,而注释掉的行会产生警告(同样,如预期的那样)。
所以世界上一切都很好,除了我不知道如何在 class Point
定义它是 "implementing" 接口 IPoint
。有没有办法做到这一点或者它不是惯用的?
这是最简单的方法:
class Point {
x: number;
y: number;
constructor(x: number, y: number) {
(this: IPoint);
this.x = x;
this.y = y;
}
}
关键部分是(this: IPoint)
。从 JS VM 的角度来看,它只是一个什么都不做的表达式,但是 Flow 需要检查将 this
转换为 IPoint
是否有效,有效地检查 class 是否实现了 IPoint
接口.
另一个简单的方法是:
interface IPoint { ... }
class Point { ... }
(Point: Class<IPoint>); // checks that Point is a class that implements IPoint
从 0.57.3
开始(很可能更早),您可以这样做:
class Point implements IPoint {
... // rest of class definition
}
我有以下使用 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
运行 npm run flow
不会像预期的那样产生任何抱怨,而注释掉的行会产生警告(同样,如预期的那样)。
所以世界上一切都很好,除了我不知道如何在 class Point
定义它是 "implementing" 接口 IPoint
。有没有办法做到这一点或者它不是惯用的?
这是最简单的方法:
class Point {
x: number;
y: number;
constructor(x: number, y: number) {
(this: IPoint);
this.x = x;
this.y = y;
}
}
关键部分是(this: IPoint)
。从 JS VM 的角度来看,它只是一个什么都不做的表达式,但是 Flow 需要检查将 this
转换为 IPoint
是否有效,有效地检查 class 是否实现了 IPoint
接口.
另一个简单的方法是:
interface IPoint { ... }
class Point { ... }
(Point: Class<IPoint>); // checks that Point is a class that implements IPoint
从 0.57.3
开始(很可能更早),您可以这样做:
class Point implements IPoint {
... // rest of class definition
}