javascript - 使用 Javascript 的 Flowtype 解释泛型

标签 javascript generics flowtype

我以前从未用静态类型语言编写过。我主要使用 Javascript 进行开发,最近我有兴趣了解更多有关 FB 的 Flowtype 的信息。

我发现文档写得很好,而且我理解了其中的大部分内容。但是我不太明白 generics 的概念.我试过用谷歌搜索一些例子/解释,但没有成功。

谁能解释一下什么是泛型,它们主要用于什么,并可能提供一个例子?

最佳答案

假设我想编写一个只存储单个值的类。显然这是人为的;我保持简单。实际上这可能是一些集合,比如 Array , 可以存储多个值。

假设我需要包装一个 number :

class Wrap {
  value: number;
  constructor(v: number) {
    this.value = v;
  }
}

现在我可以创建一个存储数字的实例,并且可以取出该数字:

const w = new Wrap(5);
console.log(w.value);

到目前为止一切顺利。但是等等,现在我还想包装一个 string !如果我天真地尝试包装一个字符串,我会得到一个错误:

const w = new Wrap("foo");

给出错误:

const w = new Wrap("foo");
                       ^ string. This type is incompatible with the expected param type of
constructor(v: number) {
                    ^ number

这行不通,因为我告诉 Flow Wrap只需 numbers .我可以重命名 WrapWrapNumber ,然后复制它,调用副本WrapString , 并更改 numberstring体内。但这很乏味,现在我要维护同一件事的两个副本。如果我每次想包装新类型时都继续复制,这很快就会失控。

但请注意 Wrap实际上并不在 value 上运行.它不关心它是否是numberstring , 或者是其他东西。它的存在只是为了存储它并在以后归还它。这里唯一重要的不变量是你给它的值和你取回的值是同一类型。使用什么特定类型并不重要,只要这两个值具有相同的值即可。

因此,考虑到这一点,我们可以添加一个类型参数:

class Wrap<T> {
  value: T;
  constructor(v: T) {
    this.value = v;
  }
}

T这里只是一个占位符。它的意思是“我不在乎你放在这里的是什么类型,但重要的是到处都使用 T,它是相同的类型。”如果我给你一个Wrap<number>您可以访问 value属性并知道它是 number .同样,如果我给你一个 Wrap<string>你知道 value对于那个例子是string .使用此新定义 Wrap ,让我们再次尝试包装 number和一个 string :

function needsNumber(x: number): void {}
function needsString(x: string): void {}

const wNum = new Wrap(5);
const wStr = new Wrap("foo");

needsNumber(wNum.value);
needsString(wStr.value);

Flow 推断类型参数并且能够理解这里的一切都将在运行时工作。如果我们尝试这样做,我们也会像预期的那样得到一个错误:

needsString(wNum.value);

错误:

20: needsString(wNum.value);
                ^ number. This type is incompatible with the expected param type of
11: function needsString(x: string): void {}
                            ^ string

(完整示例为 tryflow)

关于javascript - 使用 Javascript 的 Flowtype 解释泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44809690/

相关文章:

javascript - 将 JSON 数组中的数据放入 Javascript 数组

javascript - 如何从链接调用 facebook javascript?

javascript - MongoDB shell : How to remove specific elements in all the collections inside a DB

javascript - 使用 Javascript 和 asp.net 的表可见性

java - 在java中实例化自界泛型

java - 通用 lambda 不适用于参数

typescript - 流类型可以在方法链中加强实例的方法定义吗

java - 为什么java泛型必须删除类型信息?

javascript - 如何在 Visual Studio 2015 中使用 Flow?

reactjs - Flow 会取代 PropTypes 吗?