Using typescript to modify an immutable state using the npm package 'immutability-helper' i'm facing some strange error (at least for now). I can set an object but not merge it. Can you clarify why?
Given the following data:
export enum NetworkState {
Checking,
UpdateAvailable,
Downloading,
UpdateDownloaded,
UpToDate,
Error
}
export class Update {
public networkState: NetworkState = NetworkState.UpToDate;
public progress: number = 1;
}
export class Updater {
public client: Update = new Update();
public games :Map<string, Update> = new Map<string, Update>();
}
My goal is to update the 'progress' value of a game's 'Update' object identified by his key 'gameKey'. Without immutability in mind the solution would be:
updateGameProgress(state: Updater, payload: {gameKey: string, progress: number}){
state.games.get(payload.gameKey).progress = payload.progress
}
With immutability the solution i'm using is:
updateGameProgress(state: Updater, payload: {gameKey: string, progress: number}){
update(state, {
games: {
[payload.gameKey]: {
$set: {
networkState: state.games.get(payload.gameKey).networkState,
progress: payload.progress
}
}
}
});
}
But i'm not satisfied with this solution because it forces me to provide a value for each member of the Update object. The Update only contains two properties so it's not a big deal but what if i have 10+ properties. Unfortunately, my attempts at using $merge where unsuccessfull. The following code generates a compilation error that didn't give me a clue about what was wrong.
updateGameProgress(state: Updater, payload: {gameKey: string, progress: number}){
update(state, {
games: {
[payload.gameKey]: {
$merge: {
progress: payload.progress
}
}
}
});
}
Compilation error:
Argument of type '{ games: { [x: string]: { $merge: { progress: number; }; }; }; }' is not assignable to parameter of type 'Spec'. Type '{ games: { [x: string]: { $merge: { progress: number; }; }; }; }' is not assignable to type '{ client?: Spec; games?: Spec, never>; }'.
Types of property 'games' are incompatible. Type '{ [x: string]: { $merge: { progress: number; }; }; }' is not assignable to type 'Spec, never>'. Property '$apply' is missing in type '{ [x: string]: { $merge: { progress: number; }; }; }' but required in type '{ $apply: (v: Map) => Map; }'.
Can you clarify why this compilation error is generated ? And what could be a valid syntax to execute this merge ?
Thanks