string and string | number are compatible, but { [string]: string } and { [string]: (string | number} } are incompatible.
Am i doing something wrong?
/* @flow */
type T1 = string;
type T2 = string | number;
type T3 = { [string]: string };
type T4 = { [string]: T2 }
function main(){
var v1: T1 = 'foo';
var v2: T2 = v1;
var v3: T3 = { bar: 'bar' };
var v4: T4 = v3;
}
13: var v4: T4 = v3;
^ Cannot assign `v3` to `v4` because string [1] is incompatible with number [2] in the indexer property. [incompatible-type]
References:
5: type T3 = { [string]: string };
^ [1]
6: type T4 = { [string]: T2 }
^ [2]
Reason
This is normal and expected
If this was allowed, then you would be allowed to do
And you would get a number even though due to v3's type you should have only got a string.
Solution
Mark the objects as read-only:
Flow try link
Since they are read-only this prevents you to actually do
v4.foo = 1;.Note
This is the same for array, see this answer.
Docs
$ReadOnlyArray’s type parameter is covariant whileArray’s type parameter is invariant