如何使用接口类型执行动态类型测试?

时间:2016-07-06 16:36:26

标签: javascript flowtype

这是一个SSCCE。以下代码:

// @flow    
'use strict';

declare interface ICat {
    purr(): string;
}

class Animal {
    askToBeStrokedAsACat() {
        strokeAsACat(this); // Flow complains here
    }
}

function strokeAsACat(a: ICat) {
    a.purr();
}


class Cat extends Animal {
    purr() {
        return 'purr';
    }
}

const cat = new Cat();
cat.askToBeStrokedAsACat();

...导致FlowstrokeAsACat的函数调用中抱怨。 投诉是(为简洁起见):

property `purr` of ICat not found in class Animal

投诉是合理的,也是理解的。

根据dynamic type tests上的内容,我应该能够简单地执行以下操作:

class Animal {
    askToBeStrokedAsACat() {
        if (this instanceof ICat)
            strokeAsACat(this);
    }
}

...相反,上述内容失败了:

ICat. type referenced from value position

另外,由于接口被转换掉了,ICat在运行时不可用,因此运行时上述操作失败:

ReferenceError: ICat is not defined

因此,确定此时this句柄是ICat类似对象的唯一方法是执行以下操作:

class Animal {
    askToBeStrokedAsACat() {
        if (this instanceof Cat)
            strokeAsACat(this);
    }
}    

...但是这是nominal, not structural typing并且无法使用接口ICat的目的,就好像我添加了几个ICat-like类我必须编写动态类型测试:

(this instanceof Cat) || (this instanceof BobCat) || (this instanceof Lynx)

所以我的问题是:

  1. 有没有办法为interface执行结构动态类型测试?
  2. 还有其他方法可以有效地消除Flow对该特定线路的投诉吗?
  3. 我的Flow版本是:

    $ npm ls --depth 0 | grep flow-bin
    ├── flow-bin@0.27.0
    

1 个答案:

答案 0 :(得分:1)

  

有没有办法为接口

执行结构动态类型测试

不,这是不可能的。你可以测试对象有一个属性,它是一个函数,但你怎么知道它在运行时的签名?

但你应该很少需要它。例如,在您的代码中,您可以将askToBeStrokedAsACat留空Animal并在Cat子类中覆盖它。