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.