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

how to perform a dynamic type test with an interface type?

本文关键字:类型 测试 动态 执行 何使用 接口类型      更新时间:2023-09-26

这是一个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();

。导致 Flow 在 strokeAsACat 的函数调用时抱怨。投诉是(为简洁起见进行了编辑):

property `purr` of ICat not found in class Animal

投诉是合理和可理解的。

根据动态类型测试所写的内容,我应该能够简单地执行以下操作:

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);
    }
}    

。但这是名义上的,而不是结构类型,并且违背了使用接口的目的 ICat 如果我再添加几个ICat-like类,我将不得不将我的动态类型测试编写为:

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

所以我的问题是:

  1. 有没有办法对interface进行结构动态型式试验?
  2. 有没有其他方法可以有效地压制 Flow 对该特定线路的抱怨?

Flow版本是:

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

有没有办法对接口进行结构动态类型测试

不,这是不可能的。您可以测试对象具有属性和函数,但是在运行时如何知道它是签名?

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