Trying to intersect object types within generics inside object types.
type C = {
beers: Array<{
brand: string
}>
}
type D = {
beers: Array<{
size: number
}>
}
type CD = C & D;
var cd: CD = {beers : [{brand: 'Rothhaus', size: 0.5}]}
The variable cd does not fit the type CD. Is this the expected behavior?
Althought it works with this example.
type beerWithBrand = {
brand: string
}
type beerWithSize = {
size: number
}
type beerStock = {
beers: Array<beerWithBrand & beerWithSize>
}
var stock : beerStock = {beers : [{brand: 'Rothhaus', size: 0.5}]}
Arrays are invariant because they're mutable in JavaScript.
This means that A <: B does _not_ imply that Array<A> <: Array<B> (covariance), nor does it imply that Array<B> <: Array<A> (contravariance). For example, consider:
type A = {brand: string, size: number};
type B = {brand: string};
It's clear that A <: B (subtype). If it were true that Array<A> <: Array<B> (covariance), then this is legal:
const array: Array<A> = [{brand: 'red stripe', size: 99}];
const bArray: Array<B> = array; // because Array<A> <: Array<B>
bArray.push({brand: 'sizeless'}); // because this is an Array<B>
(array[1]: A); // This passes Flow, but it's actually not an A
Similarly, arrays cannot be contravariant because if A <: B implies Array<B> <: Array<A>, then this is legal:
const array: Array<B> = [{brand: 'red stripe'}];
const aArray: Array<A> = array; // because Array<B> <: Array<A>
(aArray[0]: A); // This passes Flow, but it's not actually an A
If you want covariant arrays, they must be read-only. You can declare this type with $ReadOnlyArray<T>
@danwang, do you have an idea how I could extend arrays from an imported, auto-generated type? Please check: https://stackoverflow.com/questions/44786085/how-to-use-flow-intersection-types-on-arrays-to-extend-an-auto-generated-type
Most helpful comment
Arrays are invariant because they're mutable in JavaScript.
This means that
A <: Bdoes _not_ imply thatArray<A> <: Array<B>(covariance), nor does it imply thatArray<B> <: Array<A>(contravariance). For example, consider:It's clear that
A <: B(subtype). If it were true thatArray<A> <: Array<B>(covariance), then this is legal:Similarly, arrays cannot be contravariant because if
A <: BimpliesArray<B> <: Array<A>, then this is legal:If you want covariant arrays, they must be read-only. You can declare this type with
$ReadOnlyArray<T>