如何键入返回子类型的泛型函数

时间:2019-02-25 19:38:42

标签: generics flowtype

根据flow's documentation,流中的泛型跟踪值。

这意味着这将引发错误:

function identity<T>(value: T): T {
  if (typeof value === 'string') {
    // $ExpectError
    return '';
  }

  return value;
}

据我所知,他们的文档中没有提到如何最好地键入这样的函数。理想情况下,您需要指定函数返回输入类型的子类型。

具体地说,我想避免输入那些不太安全的内容:

function identity<T>(value: T): (T | string) {
  ...
}

function identity(value: mixed): mixed {
  ...
}

这个谜团让我感到困惑。我真的很感谢任何帮助。

谢谢!

1 个答案:

答案 0 :(得分:0)

这是一个好问题!我能想到的最好的办法是您的代码看起来正确,并且流程可能应该支持这种情况。同时,您可以先强制转换为any,然后再强制转换为T,以便该函数具有正确的签名:

// Has the inferred signature `<T>(value: T) => T`
function identity<T>(value: T) {
  if (typeof value === 'string') {
    return ((value: any): T)
  }

  return value;
}

Try

奇怪的是,我还发现在值上使用substr并将返回类型注释为T可以使T => T毫无错误地被接受,尽管它实际上是与返回''(?!?!)

function identity<T>(value: T): T {
  if (typeof value === 'string') {
    return value.substr(0,0)
  }

  return value;
}

Try

也许文字字符串和动态字符串在幕后得到了不同的对待,从而导致类型处理方面的这种奇怪差异?

从务实的角度出发,明智的做法是为最终完成魔术的情况添加针对此功能应该处理的不同情况的单元测试。