immutable-js / immutable-js/immutable-js
Flow: Passing Map with different value types as key to another Map causes type errors (v4)
- Dominant language
- TypeScript
- Stars
- 33k
- Forks
- 1.9k
- Avg merge
- 6d 7h
- Merged PRs (30d)
- 1
Description
### What happened
When using a `Map` as a key for another `Map`, flow gets confused if the `Map` can have multiple possible value types. Here’s the flow error:
```
Error: src/model/immutable/CharacterMetadata.js:113
113: [[Map(defaultRecord), CharacterMetadata.EMPTY]],
^^^^^^^^^^^^^ object type. This type is incompatible with the expected param type of
865: static (values?: Iterable<[K, V]> | PlainObjInput): Map;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ union: type application of identifier `Iterable` | type application of polymorphic type: PlainObjInput. See: node_modules/immutable/dist/immutable.js.flow:865
Member 1:
865: static (values?: Iterable<[K, V]> | PlainObjInput): Map;
^^^^^^^^^^^^^^^^ type application of identifier `Iterable`. See: node_modules/immutable/dist/immutable.js.flow:865
Error:
113: [[Map(defaultRecord), CharacterMetadata.EMPTY]],
^^^^^^^^^^^^^ object type. This type is incompatible with
865: static (values?: Iterable<[K, V]> | PlainObjInput): Map;
^^^^^^^^^^^^^^^^ $Iterable. See: node_modules/immutable/dist/immutable.js.flow:865
Property `@@iterator` is incompatible:
865: static (values?: Iterable<[K, V]> | PlainObjInput): Map;
^^^^^^^^^^^^^^^^ property `@@iterator` of $Iterable. Property not found in. See: node_modules/immutable/dist/immutable.js.flow:865
113: [[Map(defaultRecord), CharacterMetadata.EMPTY]],
^^^^^^^^^^^^^ object type
Member 2:
865: static (values?: Iterable<[K, V]> | PlainObjInput): Map;
^^^^^^^^^^^^^^^^^^^ type application of polymorphic type: PlainObjInput. See: node_modules/immutable/dist/immutable.js.flow:865
Error:
31: entity: ?string,
^^^^^^^ null. This type is incompatible with
30: style: DraftInlineStyle,
^^^^^^^^^^^^^^^^ OrderedSet
```
### How to reproduce
```js
import { Map } from 'immutable';
type ThingStyle = Map;
type Props = {
style: ThingStyle,
entity: ?string,
};
const defaultProps: Props = {
style: Map(),
entity: null,
};
const linkThing = Map({
style: Map({ color: 'purple' }),
entity: 'LINK',
});
const cache: Map, Map> = Map(
[ [ Map(defaultProps), linkThing ] ],
);
```
If the values of the props passed to `Map` are consistent, there is no flow error, as in the following:
```js
import { Map } from 'immutable';
type Props = {
style: ?string,
entity: ?string,
};
const defaultProps: Props = {
style: '',
entity: null,
};
const linkThing = Map({
style: '',
entity: 'LINK',
});
const cache: Map, Map> = Map(
[ [ Map(defaultProps), linkThing ] ],
);
```
Contributor guide
Research direction
Start with the reproduction in the issue and inspect the Map declaration around node_modules/immutable/dist/immutable.js.flow:865, along with the reported use in src/model/immutable/CharacterMetadata.js:113. Run the shown Flow example and compare it with the consistent-value example. Done means the mixed-value Map used as a key type-checks without the reported errors.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- developer-experience
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100