We have a problem with Immutable.js
in combination with TypeScript
, and your opinion is appreciated:
In the past year, we are working on a react-redux app.
As recommended in almost any best practice, common sense and in the redux docs, our store data is immutable.
As recommended in the redux docs above, as used in many big projects, and as many boilerplates are implementing, we are using Immutable.js
.
We also write our app in TypeScript
.
The problem is, that these two (Immutable.js
and TypeScript
) cannot play nice. Once using toJS
or get
or getIn
to convert an immutable object to a normal JS object, the type is changed to any
, and this breaks the type-safety between the store and the component.
We tried
- Cast:
state.users.getIn(['counts', visits]) as number
but we hoped for a better type-safety.
- Fix
Immutable.js
's typing:
We also tried to type it ourselfs, and sometimes got as far as
interface ImmutableMap<T> {
get<K extends keyof T>(name: K): T[K];
set<S>(k: string, o: S): ImmutableMap<T & S>;
getIn(searchKeyPath: any[], notSetValue?: any): T;
}
(idea from here)
Assuming that getIn
is only called with toJS
and always return a JS object (which we do sometimes in our higher-order-component - but that’s another story).
But this is crap and a big hack.
We came to the conclusion that it is impossible to fix the type-safety of Immutable.js
ourselves.*
- Vanilla:
We tried to go vanilla, with object spread, but as the data structure became complicated, the merging of immutable objects became too complex and generated an unreadable code:
{
...state,
profiles: {
...state.profiles,
[id]: {
...state.profiles[id],
meta: {
...state.profiles[id].meta,
[sub]: payload,
},
},
},
And we ended up building another Immutable.js
library that we will need to maintain - too much code to support.
about the record option
We want to avoid using record
- it produces a big pile of js code in the end browser, that is needed only for TypeScript
and not necessary for the user, it is hell to maintain, and at the end does not share the full, same API as a pure JS object. I worked with it in past projects, and it was a very a bad experience.
Questions
My questions are for people who created/working with complicated React-Redux apps:
- Does anybody suffer from the same issue? Got a good solution to work with
Immutable.js
andTypeScript
? - Anybody got a recommendation for a better library/solution, for good immutability and type-safety?