这是一个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
投诉是合理的,也是理解的。
根据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)
所以我的问题是:
interface
执行结构动态类型测试?我的Flow
版本是:
$ npm ls --depth 0 | grep flow-bin
├── flow-bin@0.27.0
答案 0 :(得分:1)
有没有办法为接口
执行结构动态类型测试
不,这是不可能的。你可以测试对象有一个属性,它是一个函数,但你怎么知道它在运行时的签名?
但你应该很少需要它。例如,在您的代码中,您可以将askToBeStrokedAsACat
留空Animal
并在Cat
子类中覆盖它。