Javascript 使用动态函数引用时出现流错误

Javascript 使用动态函数引用时出现流错误,javascript,react-native,flowtype,Javascript,React Native,Flowtype,我在React项目中有一个函数,它迭代一个数组,并将每个项与另一个变量进行比较。现在,数组中的项可以是字符串或正则表达式。因此,我保留了一个名为compareFn的变量,并根据项目的类型将其引用指向equal或patternMatch。下面是示例代码 const equal = (privilege: string, whitelistVal: string) => privilege === whitelistVal; const patternMatch = (privilege: s

我在React项目中有一个函数,它迭代一个数组,并将每个项与另一个变量进行比较。现在,数组中的项可以是字符串或正则表达式。因此,我保留了一个名为
compareFn
的变量,并根据项目的类型将其引用指向
equal
patternMatch
。下面是示例代码

const equal = (privilege: string, whitelistVal: string) => privilege === whitelistVal;
const patternMatch = (privilege: string, whitelistPattern: RegExp) => whitelistPattern.test(privilege);

...

const compareFn = whitelistItem instanceof RegExp ? patternMatch : equal;
if (compareFn(privilegeItem, whitelistItem)) {
  // Do something
}
使用此代码,我在第36行中突出显示了一个流错误
whitelistItem
,如下所示:

无法调用绑定到whitelistPattern的whitelistItem的compareFn 因为字符串[1]与RegExp[2]不兼容

35 | const compareFn=RegExp的whitelistItem实例? 模式匹配:相等
36 |如果(比较项(privilegeItem,白名单项)){

在我看来,Flow似乎无法识别函数引用的条件赋值。如能帮助解决此问题,我们将不胜感激


我使用的是Flow 0.71.0和React Native 0.55.3。

以下是一些有效的方法:

const equal = (privilege: string, whitelistVal: string) => privilege === whitelistVal;
const patternMatch = (privilege: string, whitelistPattern: RegExp) => whitelistPattern.test(privilege);


declare function getCompareFn(
  whitelistItem: RegExp
): (string, RegExp) => boolean;
declare function getCompareFn(
  whitelistItem: string
): (string, string) => boolean;

function getCompareFn(whitelistItem) {
  return whitelistItem instanceof RegExp ? patternMatch : equal;
}

const whitelistItem1 = /test/;
const whitelistItem2 = "test";

const privilegeItem = "test";

getCompareFn(whitelistItem1)(privilegeItem, whitelistItem1);
getCompareFn(whitelistItem2)(privilegeItem, whitelistItem2);
链接到

Flow用于确定
getCompareFn
的精确类型签名,否则很难表达。请注意,Flow并不强制声明的正确性,因此您有责任仔细分析并确保声明的类型确实与函数的实现匹配,但在本例中,这是公平的微不足道的

不使用
声明
,我们可以做以下几点:

// type alias to represent generic compare function
type CompareFn<T> = (string, T) => boolean;

function getCompareFn(
  whitelistItem: RegExp | string
): CompareFn<string> | CompareFn<RegExp> {
  return whitelistItem instanceof RegExp ? patternMatch : equal;
}
然而,flow不能断言这一点

再进一步,我们可以尝试这样来解决问题:

function getCompareFn<T: RegExp | string>(whitelistItem: T): CompareFn<T> {
  return whitelistItem instanceof RegExp ? patternMatch : equal;
}

如果使用<代码> var >代码>而不是<代码> const <代码>,你也会得到同样的错误吗?也考虑将你的条件测试包括在括号内:<代码>(WeleListITEM的ReXEP)……/代码>对于两个选项都得到相同的错误-这可能是有用的。
function getCompareFn<T: RegExp | string>(whitelistItem: T): CompareFn<T> {
  return whitelistItem instanceof RegExp ? patternMatch : equal;
}
const whitelistItem1 = /test/;
const whitelistItem2 = "test";

const privilegeItem = "test";

interface TestString {
  test(s: string): boolean;  
};

// RegExp has method `test`, therefore structurally implements TestString

class EqualsString implements TestString {
   _value: string;
   constructor(value: string) {
      this._value = value; 
   }
   test(s) {
      return s === this._value; 
   }
}

function getStringTester(whitelistItem: string | RegExp): TestString {
  if (whitelistItem instanceof RegExp) {
    return whitelistItem;
  } else {
    return new EqualsString(whitelistItem);
  }
}

const t1 = getStringTester(whitelistItem1);
const t2 = getStringTester(whitelistItem2);

const b1: boolean = t1.test(privilegeItem);
const b2: boolean = t2.test(privilegeItem);