【问题标题】:how to declare that a given class implements an interface in Facebook Flow?如何声明给定类在 Facebook Flow 中实现接口?
【发布时间】:2016-11-08 11:25:14
【问题描述】:

我有以下使用 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 的地方明确说明它。有没有办法这样做还是不是惯用的?

【问题讨论】:

    标签: javascript node.js flowtype


    【解决方案1】:

    这是最简单的方法:

    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 是否有效,有效地检查类是否实现了 IPoint 接口。

    【讨论】:

    • 您能否详细说明,或提供一些文档?只是想弄清楚为什么会这样。谢谢!
    • 如果您的 linter 抱怨 no-unused-expressions,您可能需要改写为 void (this: IPoint);
    【解决方案2】:

    另一种简单的方法是:

    interface IPoint { ... }
    class Point { ... }
    
    (Point: Class<IPoint>); // checks that Point is a class that implements IPoint
    

    【讨论】:

    • 这同样适用于非 ES6 类的东西吗?假设我有如下函数:type ISomeAPI = { apiMethod: (..args) =&gt; void }const myFunc = (service: Class&lt;ISomeAPI&gt;) =&gt; { ... } 服务可以是普通对象({ apiMethod: () =&gt; {...} })还是函数对象(例如function ClassName() {})?
    【解决方案3】:

    截至0.57.3(很可能更早),可以做到:

    class Point implements IPoint {
    ... // rest of class definition
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-26
      • 2013-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多