【问题标题】:Flow type, what do `+` and `-` do in a generic declaration?流类型,`+` 和 `-` 在泛型声明中做了什么?
【发布时间】:2018-12-19 00:19:46
【问题描述】:

类似:

declare class $ReadOnlyArray<+T>
declare type React$Element<+ElementType: React$ElementType>
interface $Iterator<+Yield,+Return,-Next>

不是出现在属性前面的那种,这里回答Flow type, What does the `+` symbol mean in front a property?

【问题讨论】:

  • 它们是只读和只写的泛型参数
  • 是否有关于协变/逆变泛型参数的体面文档?
  • @Li357 你能详细说明一下吗? “只读”一词让我想到了 $ReadOnly ,这根本不是同一种情况。
  • @JamesKraus 不是真的。这些术语对我来说有些新鲜,但在使用过 Java 之后,这个概念非常熟悉。
  • @RichN,+/- 符号表示属性或类型参数是协变/逆变的。它通常被称为只读和只写,因为这是最终结果。例如$ReadOnly 将对象的所有属性标记为协变。

标签: javascript flowtype


【解决方案1】:

这是我的理解,可能不完整。

泛型类型中的协方差,如type Container&lt;+T&gt; = {},意味着:如果AB 的子类型,那么Container&lt;A&gt;Container&lt;B&gt; 的子类型。例如,这是允许的:

type Container<+T> = {};
class Parent {};
class Child extends Parent {};
function x(a: Container<Parent>) {}
const container: Container<Child> = {};
x(container);

因为ChildParent 的子类型。但是如果你删除了+,它就不再被允许,并且Flow在x(container)上给出一个错误,因为container不是Container&lt;Parent&gt;类型的有效值。

当然,逆变是相反的:type Container&lt;-T&gt; = {} 表示如果AB 的子类型,那么Container&lt;B&gt;Container&lt;A&gt; 的子类型。所以这是合法的:

type Container<-T> = {};
class Parent {};
class Child extends Parent {};
function x(a: Container<Child>) {}
const container: Container<Parent> = {};
x(container);

请注意,我对Container&lt;+T&gt;Container&lt;-T&gt; 的定义根本没有使用T 类型。如果是这样,那么它的使用位置就会受到限制,类似于对接口中的逆变或协变属性的限制(即,它们变为只读或只写)。我还没有制定出这些规则的细节。

【讨论】:

  • 是的,我很久以前就问过这个问题,我想我现在有正确的理解,但是这个问题并没有引起太大的关注,所以我没有回答我自己的问题。此外,我现在大部分都放弃了 Flow 并使用了 TypeScript,它没有这个功能。不确定 Flow 文档现在的状态如何,但当时博客实际上解释得更好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-28
  • 2015-12-14
  • 2018-12-14
  • 1970-01-01
  • 2019-04-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多