DEV Community

Martin Maier
Martin Maier

Posted on

Replicate immutable data in typescript with the ReplicationBuilder

ReplicationBuilder Demo

The ReplicationBuilder is a typescript tool to clone immutable data objects in a typesafe, refactorable and well readable way.

In our single page applications we often use different implementations of redux to handle our application state.

The more complex the data structures become, the more complex becomes the code that handles the immutable states when using Object.assign() or something like that.

Therefore this often ends up in code that is really hard to read and maintain.

So my intention was to create a tool that can handle immutable data in a typesafe, refactorable and well readable way.

The powerful keyof-feature introduced in Typescript 2.1 to lookup for objects properties in a typesafe way helped me a lot to solve that.

The result i called ReplicationBuilder and is a typesafe, fluent API to build replications of an object.

Together with some other small helpers its published in the npm package "typescript-immutable-helper".

The source code is hosted on GitHub Repository

I would be glad for some feedback or if you want to constribute.

 

Syntax

simply replace property by with new value

return ReplicationBuilder.forObject(state).property('party')
   .replaceValueOf('name').with('MyParty')
   .build()
Enter fullscreen mode Exit fullscreen mode

replace property depending on old value

return ReplicationBuilder.forObject(state).property('party')
   .replaceValueOf('partymemberArray').by((oldPartymemberArray) => [...oldPartymemberArray, 'new partymember'])
   .build()
Enter fullscreen mode Exit fullscreen mode

clone property and apply some function on it

return ReplicationBuilder.forObject(state)
   .replaceValueOf('party').withCloneAndDo((clonedParty) => clonedParty.addPartyMember('new partymember'))
   .build()

Enter fullscreen mode Exit fullscreen mode

Characteristics

typesafe properties

typesafe property values

chainable

return ReplicationBuilder.forObject(state)
    .property('party').replaceValueOf('name').with('MyParty').replaceValueOf('members').by((members) => [...members, newMember])
    .property('initiator').replaceValueOf('prename').with('Party').replaceValueOf('surname').with('guy')
    .build();
Enter fullscreen mode Exit fullscreen mode

refactorable and easy to read

Usage

  1. Load an object by calling ReplicationBuilder.forObject()
  2. Navigate down the object tree through the typesafe function property()
  3. Modify a property with either (see syntax paragraph above)
    • replaceValueOf('prop').with(newValue:T)
    • replaceValueOf('prop').by((T) => newValue:T)
    • replaceValueOf('prop').withCloneAndDo((clonedProp) => clonedProp.doSomething()
    • removeProperty('prop') to remove the property in the resulting object
  4. Repeat step 3 and 4 until all modifications are done
  5. Produce the replica with build()

Behaviour

  • deep copies the source object
  • freeze in --> freeze out. If the source object was frozen (for detecting manipulations while development), then the produced replica will also be deep frozen.
  • warning if source object is not deep frozen (produced replica will be deep frozen)

Demo

ReplicationBuilder Demo

originally posted on http://maimart.de

Top comments (0)