3

Something like:

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

Not the kind that appears in front of properties, which is answered here Flow type, What does the `+` symbol mean in front a property?

RichN
  • 6,181
  • 3
  • 30
  • 38
  • 1
    They are read-only and write-only generic parameters – Andrew Li Jul 11 '18 at 05:04
  • Are there any decent docs on covariant/contravariant generic parameters? – James Kraus Jul 11 '18 at 13:34
  • @Li357 Can you elaborate? The term "read-only" makes me think of $ReadOnly which is not at all the same case. – RichN Jul 11 '18 at 14:51
  • @JamesKraus Not really. The terms are somewhat new for me but having worked with Java the concept are quite familiar. – RichN Jul 11 '18 at 14:55
  • @RichN, the +/- symbols mark that a property or type parameter is covariant/contravariant. It's often referred to as read-only and write-only since that's the end result. e.g. $ReadOnly marks all the properties of an object as covariant. – James Kraus Jul 11 '18 at 14:57

1 Answers1

0

Here's my understanding, possibly incomplete.

Covariance in a generic type, like type Container<+T> = {}, means: if A is a subtype of B, then Container<A> is a subtype of Container<B>. So for example, this is allowed:

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

because Child is a subtype of Parent. But if you remove the +, it's no longer allowed, and Flow gives an error on x(container), because container is not a valid value of type Container<Parent>.

And of course contravariance is the opposite: type Container<-T> = {} means that if A is a subtype of B, then Container<B> is a subtype of Container<A>. So this is legal:

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

Notice that my definition of Container<+T> or Container<-T> didn't make use of type T at all. If it did, there would be restrictions on where it could be used, similar to how there are restrictions on what you can do with contravariant or covariant properties in an interface (i.e., they become read-only or write-only). I haven't worked out the details of these rules yet.

aldel
  • 6,489
  • 1
  • 27
  • 32
  • Yeah I asked this question a long time ago, I think I now have the right understanding but the question didn't get much traction so I didn't answer my own question. Also I've mostly abandoned Flow and used TypeScript now, which doesn't have this functionality. Not sure how's the state of the Flow documentation now but back then the blog actually explained it better. – RichN Sep 01 '21 at 01:39