Flow seems to think the result of an object spread on a map object is just Object, rather than the original type. This makes it hard to safely merge multiple map objects into one.
/* @flow */
type A = { [string]: number };
const foo: A = { a: 5 };
foo.b = '5'; // Error, as expected.
const bar = { ...foo };
bar.b = '5'; // No error, despite not matching A's definition.
See https://flow.org/try/#0PQKgBAAgZgNg9gdzCYAoVAXAngBwKZgCCYAvGAN5gDaAzhgE4CWAdgOYC6AXGMwK4C2AIzz0wAXwDc6AMZxmdMFDhxuxMpQCG3AKzipqJXAB0g0mADk28xLDBgYAKL16cegBowGmmDwAPfNIYeAAmRjJyCoIaoupgRvGGeuhR9CZmlta29gBycD7Orh7BeDQ4jEE8cBhg-BoY0gAWLKxE5t7FUCzljHJGQA.
I think this may be a distinct issue from https://github.com/facebook/flow/issues/6505, since this one deals with map objects rather than exact objects.
Agreed that this a bug, and different from #6505.
These are called objects with _indexer properties_ (commenting with this
keyword to improve searchability). A “Map object” may quite reasonably
be interpreted as an instance of Map.
@wchargin good point, I've updated the title of this issue to be more precise.
Now that the Object type degenerates to any this behavior is even worse, and flow now thinks the spread object is maybe a string or a number or void.
Combined with #6656 this now means that
// @flow
type objmap = {[string]: number};
function bar(o: objmap): objmap {
return [''].reduce({...o});
}
fails after v0.87.0
This now errors as expected in master