gpt4 book ai didi

flowtype - Flow 如何解释泛型类型?

转载 作者:行者123 更新时间:2023-12-04 01:10:10 27 4
gpt4 key购买 nike

我想了解 Flow 如何决定泛型类型使用什么类型,以及是否有办法控制推断泛型类型的级别(我的意思是进一步解释)。

This question is inspired by How to type a generic function that returns subtypes. I think there is a distinction between the two questions because this one focuses on understanding how T is chosen, where as the linked on is focuses on typing the return type of a function.



恒等函数是一个很好的剖析示例。它的类型相当简单
function identity<T>(value: T): T;

这似乎是足够的信息来了解实现应该是什么。但是,我觉得这种类型不足以知道身份函数实际上是做什么的。例如,我们可以(正如链接的问题试图做的那样),
function identity<T>(value: T): T {
if (typeof value === 'string') {
return '';
}

return value;
}

Try Flow

这不会进行类型检查,Flow 会提示返回空字符串。然而,我想在许多语言中这会很好——我们将返回一个 stringstring已输入,否则返回原 value类型 T ——但出于某种原因,Flow 不喜欢这样。

this answer 加剧了我的困惑, 我们可以返回 value.substr(0, 0)而不是空字符串, Flow 将不再提示,并且无法返回严格相等的值,
function identity<T>(value: T): T {
if (value === '') {
return '';
}

return value;
}

Try Flow

我认为造成这种差异的一个主要原因是,除了“JavaScript 类型”之外,文字还可以像 Flow 中的类型一样。例如,
const x: 5 = 5; // literal type
const x: number = 5; // JavaScript type

都是有效的。然而,这意味着当我们有一个 T => T 类型的函数时,我们不知道 Flow 是将文字类型还是 JavaScript 类型推断为类型。

我想知道是否有某种方法可以知道 Flow 对函数中的泛型类型推断出什么,或者是否有办法将泛型类型的范围限定在“文字”级别或“JavaScript”级别。有了这种能力,我们可以键入将值强制为该类型的默认值的函数(即,字符串将变为空字符串,数字将变为 0)。这里函数的类型实际上是 T => T ,但希望可以防止 Flow 提示返回默认值。

最佳答案

如果没有直接回答问题,希望在这里能说明正在发生的事情。

让我们首先举你的第一个例子:

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

return value;
}

函数签名是 identity<T>(T): T .这基本上是说:
  • 我们正在创建一个新类型 T这可以是任何东西( <T> )。
  • 我们的函数将接收一个 T 类型的参数。 .
  • 我们的函数将返回 T 类型的值.

  • 从现在开始,这些限制都不会改变, T 的类型也不会改变。也不会改变。 identity必须返回 T 的确切类型,不是其类型的子集。让我们来看看为什么。
    identity<'some string'>('some string');

    在这种情况下 T 的类型是文字类型, 'some string' .在调用上述函数的情况下,我们会发现 typeof value === 'string'并尝试返回 '' , string . string但是,是 T 的父类(super class)型这是 'some string' ,所以我们违反了函数的契约。

    在简单字符串的情况下,这一切似乎都相当人为,但实际上是必要的,并且在扩展到更复杂的类型时更加明显。

    让我们看看我们奇怪的身份函数的正确实现:
    function identity<T>(value: T): T | string {
    if (typeof value === 'string') {
    return '';
    }

    return value;
    }
    T 的返回类型只有完全匹配的东西才能满足 T ,在我们签名的情况下只能是 value .但是,我们有一个特殊情况,即 identity可能会返回 string ,所以我们的返回类型应该是 T | string 的并集(或者,如果我们想要 super 具体, T | '' )。

    现在让我们继续第二个例子:
    function identity<T>(value: T): T {
    if (value === '') {
    return '';
    }

    return value;
    }

    在这种情况下,流只是不支持 value === ''作为一种细化机制。流程中的细化非常挑剔,我喜欢将其视为在我的代码上运行的一些简单正则表达式的列表。确实只有将类型细化为字符串的方法,那就是使用 typeof value === 'string' .其他比较不会细化到字符串。精炼泛型肯定也​​有一些奇怪的地方,但像这样的东西工作正常(精炼确实如此,当然它仍然表现出以前与泛型相关的错误):
    function identity<T>(value: T): T {
    if (typeof value === 'string' && (value: string) === '') {
    return '';
    }

    return value;
    }

    ( Try )

    至于 substr例如,这对我来说绝对是一个错误。似乎你可以用 String 上的任何方法做同样的事情。返回 string ,例如 concatslice .

    I would like to know if there is some way of either knowing what Flow infers for generic types in a function



    在函数体流中并没有真正推断出泛型的类型。泛型有一个具体的定义( TT ,本质上是一个未知类型,除非它有边界,在这种情况下,它是一个与这些边界匹配的未知类型)。 Flow 可以推断进入函数调用的参数类型,但这应该与函数的编写方式无关。

    or if there is a way to scope the generic type to be at the "literal" level or "JavaScript" level. With this ability, we could type function that coerces values to the default value for that type (i.e., strings would go to the empty string, numbers would go to 0). Here the type of the function would effectively be T => T, but hopefully Flow could be prevented from complaining about returning the default values.



    这里的问题是这将不再是 T => T .正如我上面所展示的,破坏这样的实现是微不足道的。

    关于flowtype - Flow 如何解释泛型类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55736465/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com