Contravariance just means "varies in the opposite direction" (and covariance just means "varies in the same direction"). In the context of subtype relationships, it refers to cases when a compound type is a subtype of another type if-and-only-if one its parts is a supertype of the same part in the other type.
By "compound type" I just mean a type that has other component types. Languages like Haskell, Scala, and Java handle this by declaring that a type has parameters (Java calls this "generics"). From a brief look at the link to the Flow docs, it looks like Flow doesn't formalise parameters, and is effectively considering the type of each property to be a separate parameter. So I'll avoid specifics and just talk about types that are made up of other types.
Subtyping is all about substitutability. If someone wants a T, I can give them a value of any subtype of T, and nothing will go wrong; the things they're "allowed" to do with the thing they asked for are only the things that are valid to do with any possible T. The variance comes in when the types have substructure of other types. If someone asks for a type with a structure that includes a component type T, and I want to give them a value with a type that has the same structure but the component type is S, when is that valid?
If the component type is there because they can obtain T values using the object they're asking for (like reading a property, or calling a method that returns T values), then when I give them my value they'll be getting S values out of it instead of the T values they were expecting. They'll want to do Tish things with those values, which will only work if S is a subtype of T. So for the compound type I have to be a subtype of the one they want, the component of the one I have must be a subtype of the component in the one they want. This is covariance.
On the other hand, if the component type is there because they can send T values to the object they're asking for (like writing a property, or calling a method that takes T values as arguments), then when I give them my value it will be expecting them to send it S values instead of T ones. My object will want to do Sish things with the T values the other person is going to send to it. That's only going to work if T is a subtype of S. So in this case, for the compound type I have to be a subtype of the one they want, the component of the one I have must be a supertype of the component in the one they want. This is contravariance.
Simple function types are a concrete example that is generally easily understood with a little thought. A function type written in Haskell notation is like ArgumentType -> ResultType; this itself is a compound type with two component types, so we can ask whether one function type can be substituted for (is a subtype of) another function type.
Lets say I've got an list of Dog values, and I need to map a function over it to turn it into a list of Cat values. So the function that does the mapping is expecting me to give it a function of type Dog -> Cat.
Can I give it a function of type GreyHound -> Cat? No; the mapping function will call my function on all of the Dog values in the list, and we don't know that they are all GreyHound values.
Can I give it a function of type Mammal -> Cat? Yes; my function can only do things that are valid for any Mammal, which obviously includes all of the Dog values in the list that it will be called on.
Can I give it a function of type Dog -> Siamese? Yes; the mapping function will use the Siamese values returned by this function to build a list of Cat, and Siamese values are Cat values.
Can I give it a function of type Dog -> Mammal? No; this function might turn a Dog into a Whale, which won't fit in the list of Cat the mapping function needs to build.