immutability-patterns
Immutability Patterns in TypeScript:
Understanding Immutability:
Immutability is a design principle that ensures data cannot be altered after creation. It leads to safer code by preventing unexpected changes, making the application state more predictable and easier to debug.Readonly Keyword:
interface Person {
readonly name: string;
readonly age: number;
}
let person: Person = { name: 'John', age: 30 };
// Trying to change the name or age will result in a TypeScript error.Const Assertions:
let immutableObject = { x: 10, y: 20 } as const;
// immutableObject.x = 25; // This line would cause a TypeScript error.Using ReadonlyArray and ReadonlyMap:
let readonlyArray: ReadonlyArray<number> = [1, 2, 3];
// readonlyArray[0] = 10; // Error, cannot modify an index of a readonly array.
let readonlyMap: ReadonlyMap<string, number> = new Map();
// readonlyMap.set('key', 1); // Error, cannot add entries to a readonly map.Immutable Data Libraries:
Use Immutable.js to manage collections like List, Stack, Map, etc., which offer methods that return new instances rather than modifying the original instance, ensuring immutability.Object.freeze:
let frozenObject = Object.freeze({ name: 'John' });
// frozenObject.name = 'Jane'; // Error, cannot assign to 'name' because it is a read-only property.Spread Operator for Copies:
let originalArray = [1, 2, 3];
let copiedArray = [...originalArray];
// Now, copiedArray is a shallow copy of originalArray.Immer Library for Immutable State:
import produce from 'immer';
let baseState = { counter: 0 };
let nextState = produce(baseState, draftState => {
draftState.counter++;
});
// baseState is untouched, nextState is a new object with counter incremented.Structural sharing means that when a new version of an object is created after a change, it reuses most of the existing structure. This efficient practice is common in functional programming and helps in managing immutable states.