Typed Object Accumulator
Typed Object Accumulator is a TypeScript library that provides a type-safe way to dynamically accumulate and manage object properties. It allows you to combine multiple objects while maintaining full TypeScript type information, giving you the flexibility of dynamic objects with the safety of static typing. The library is designed to be immutable, chainable, and fully type-aware, making it ideal for building complex objects incrementally in a type-safe manner.
Documentation available here
Description
Typed Object Accumulator is a specialized TypeScript utility library designed to solve the common challenge of building complex objects incrementally while maintaining full type safety. Unlike traditional object manipulation in JavaScript, which often sacrifices type information when combining objects, this library preserves and evolves type definitions as you add properties.
Core Features
-
Type-Safe Property Accumulation: The
ObjectAccumulator
class allows you to progressively add properties from multiple objects while TypeScript tracks the combined type information. -
Immutable Design: Each operation returns a new accumulator instance with updated type information, ensuring your data remains predictable and side-effect free.
-
Chainable API: Methods can be chained together for a fluent, readable coding style when building complex objects.
-
Comprehensive Property Management: Beyond simple accumulation, the library provides methods for checking property existence, removing properties, retrieving values, and iterating over accumulated data.
-
Full TypeScript Integration: The library leverages TypeScript's advanced type system to provide autocompletion and type checking for all accumulated properties.
Key Components
The library consists of a single primary class, ObjectAccumulator<T>
, which manages the accumulation of object properties and maintains type information. It provides methods for:
- Adding properties with
accumulate()
- Retrieving values with
get()
or direct property access - Checking property existence with
has()
- Removing properties with
remove()
- Getting all keys with
keys()
- Getting all values with
values()
- Getting the size with
size()
- Clearing all properties with
clear()
- Iterating over properties with
forEach()
- Transforming properties with
map()
Use Cases
Typed Object Accumulator is particularly useful for:
- Building configuration objects incrementally
- Combining data from multiple sources with type safety
- Creating complex state objects in a functional programming style
- Managing form data with evolving structure
- Implementing builder patterns with full type information
By using Typed Object Accumulator, developers can enjoy the flexibility of dynamic object manipulation without sacrificing the benefits of TypeScript's static type checking.
How to Use
Creating a new ObjectAccumulator
Description: Initialize a new empty accumulator to start collecting object properties.
import { ObjectAccumulator } from 'typed-object-accumulator';
// Create a new empty accumulator
const accumulator = new ObjectAccumulator<{}>();
// Or with type inference
const typedAccumulator = new ObjectAccumulator<{ initialType: string }>();
Accumulating Objects
Description: Add properties from objects to the accumulator while maintaining type information.
import { ObjectAccumulator } from 'typed-object-accumulator';
const accumulator = new ObjectAccumulator();
// Add a single object
const withUser = accumulator.accumulate({ name: "John", age: 30 });
console.log(withUser.name); // "John"
console.log(withUser.age); // 30
// Chain multiple accumulations
const fullData = accumulator
.accumulate({ name: "John", age: 30 })
.accumulate({ city: "New York", country: "USA" })
.accumulate({ isActive: true, score: 95.5 });
// All properties are now available with type safety
console.log(fullData.name); // "John"
console.log(fullData.city); // "New York"
console.log(fullData.isActive); // true
Retrieving Values
Description: Get a value from the accumulator using a key.
import { ObjectAccumulator } from 'typed-object-accumulator';
const accumulator = new ObjectAccumulator()
.accumulate({ name: "John", age: 30 });
// Get values using the get method
const name = accumulator.get("name"); // "John"
const age = accumulator.get("age"); // 30
const unknown = accumulator.get("unknown"); // undefined
// Or access directly with type safety
console.log(accumulator.name); // "John"
Checking if a Key Exists
Description: Verify if a specific key is present in the accumulator.
import { ObjectAccumulator } from 'typed-object-accumulator';
const accumulator = new ObjectAccumulator()
.accumulate({ name: "John", age: 30 });
// Check if keys exist
const hasName = accumulator.has("name"); // true
const hasEmail = accumulator.has("email"); // false
Removing Properties
Description: Remove a property from the accumulator.
import { ObjectAccumulator } from 'typed-object-accumulator';
const accumulator = new ObjectAccumulator()
.accumulate({ name: "John", age: 30, city: "New York" });
// Remove a property
const withoutAge = accumulator.remove("age");
console.log(withoutAge.has("age")); // false
console.log(withoutAge.has("name")); // true
console.log(withoutAge.has("city")); // true
Getting All Keys
Description: Retrieve an array of all keys in the accumulator.
import { ObjectAccumulator } from 'typed-object-accumulator';
const accumulator = new ObjectAccumulator()
.accumulate({ name: "John", age: 30 })
.accumulate({ city: "New York" });
// Get all keys
const keys = accumulator.keys(); // ["name", "age", "city"]
Getting All Values
Description: Retrieve an array of all values in the accumulator.
import { ObjectAccumulator } from 'typed-object-accumulator';
const accumulator = new ObjectAccumulator()
.accumulate({ name: "John", age: 30 });
// Get all values
const values = accumulator.values(); // ["John", 30]
Getting the Size
Description: Get the number of key-value pairs in the accumulator.
import { ObjectAccumulator } from 'typed-object-accumulator';
const accumulator = new ObjectAccumulator();
console.log(accumulator.size()); // 0
const withData = accumulator.accumulate({ name: "John", age: 30 });
console.log(withData.size()); // 2
const moreData = withData.accumulate({ city: "New York", country: "USA" });
console.log(moreData.size()); // 4
Clearing the Accumulator
Description: Remove all properties and return a new empty accumulator.
import { ObjectAccumulator } from 'typed-object-accumulator';
const accumulator = new ObjectAccumulator()
.accumulate({ name: "John", age: 30 });
// Clear all properties
const emptyAccumulator = accumulator.clear();
console.log(emptyAccumulator.size()); // 0
console.log(emptyAccumulator.keys()); // []
Iterating with forEach
Description: Execute a callback function for each key-value pair in the accumulator.
import { ObjectAccumulator } from 'typed-object-accumulator';
const accumulator = new ObjectAccumulator()
.accumulate({ a: 1, b: 2, c: 3 });
// Iterate over all entries
accumulator.forEach((value, key, index) => {
console.log(`${index}: ${key} = ${value}`);
});
// Output:
// 0: a = 1
// 1: b = 2
// 2: c = 3
Mapping Values
Description: Create a new array by applying a function to each key-value pair.
import { ObjectAccumulator } from 'typed-object-accumulator';
const accumulator = new ObjectAccumulator()
.accumulate({ name: "John", age: 30, city: "New York" });
// Map entries to a new format
const formattedEntries = accumulator.map((value, key) => `${key}: ${value}`);
// ["name: John", "age: 30", "city: New York"]
VERSION Constant
Description: Access the current version of the library.
import { VERSION } from 'typed-object-accumulator';
console.log(`Using typed-object-accumulator version: ${VERSION}`);
Social
Languages
Getting help
If you have bug reports, questions or suggestions please create a new issue.
Contributing
I am grateful for any contributions made to this project. Please read this to get started.
Supporting
The first and easiest way you can support it is by Contributing. Even just finding a typo in the documentation is important.
Financial support is always welcome and helps keep both me and the project alive and healthy.
So if you can, if this project in any way. either by learning something or simply by helping you save precious time, please consider donating.
License
This project is released under the MIT License.
By developers, for developers...