2016-07-06 99 views
2

我使用流量以下代碼:如何聲明給定的類在Facebook 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產量沒有抱怨不如預期,而註釋掉線產生警告(再次,符合市場預期)。

因此,除了我不知道如何在類Point被定義爲「實現」接口IPoint的地方明確表達它的一切情況。有沒有辦法這樣做,還是不習慣?

回答

5

這裏是做最簡單的方法:

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

的關鍵部分是(this: IPoint)。從JS VM的角度來看,這只是一個什麼也不做的表達式,但Flow需要檢查是否鑄造thisIPoint是有效的,從而有效地檢查類是否實現了接口。

+0

你能否解釋,或者提供一些文檔?只是試圖看到這個工程的原因。謝謝! –

+1

如果你的linter抱怨['no-unused-expressions'](http://eslint.org/docs/rules/no-unused-expressions),你可能需要寫'void(this:IPoint);'而不是。 –

1

另一種簡單的方法來做到這一點是:

interface IPoint { ... } 
class Point { ... } 

(Point: Class<IPoint>); // checks that Point is a class that implements IPoint 
0

由於0.57.3(而且很有可能更早),可以這樣做:

class Point implements IPoint { 
... // rest of class definition 
} 
相關問題