Mapwise is a lightweight, type-safe utility library for TypeScript that provides two helper functions:
keyBy: Transform an array into aMapkeyed by a specified property or computed value.
Optionally, provide a value transformer to choose what each map entry stores.groupBy: Group array items into aMapwhere each key corresponds to an array of items sharing a common property or computed value.
Optionally, provide a value transformer to transform the grouped items however you’d like.
Mapwise is designed after both lodash and the recent Map.groupBy function.
Using Maps instead of Records (as in lodash) offers a clear type safety advantage. When you access a key in a Record via bracket notation (e.g. result[nonExistingKey]), TypeScript may not always include undefined in the inferred type — even if the key is absent — potentially masking runtime errors. In contrast, Maps require using the get method (e.g. resultMap.get(nonExistingKey)), which correctly returns a type of T | undefined. This ensures that the possibility of a missing key is always accounted for in consuming code.
- Type Safety: Leverage TypeScript’s strong typing with overloads that enforce correct usage for property‑ or function‑based keys.
- Flexible Keying & Values:
- Provide a property name or callback function to determine the map/group keys (a key extractor).
- Optionally, provide a property name or callback function (a value transformer) to determine the stored values.
- Explicit Nullish Handling: Fine‑grained control over whether you skip
null/undefineditems and keys (viaexcludeNullish: true).
bun add mapwiseNot using Bun? Ehem.. I guess that's OK too..
import { keyBy, groupBy } from "mapwise";
// Or as separate ES modules:
import { keyBy } from 'mapwise/keyBy';
import { groupBy } from 'mapwise/groupBy';const items: Person[] = [
{ id: 1, name: "Alice", group: "admin" },
{ id: 2, name: "Bob", group: "user" },
{ id: 3, name: "Diana", group: "user" },
];
const mapById = keyBy(items, "id");
// Result: Map<number, Person>const mapIdToName = keyBy(items, "id", "name");
// Result: Map<number, string>const mapByCustom = keyBy(items, (item, index) => {
// Use a key extractor callback. Handle nullish items as needed.
return item ? item.id : index;
});const groupsByGroup = groupBy(items, "group");
// Result: Map<string, Person[]>const groupsByGroupNames = groupBy(items, "group", "name");
// Result: Map<string, string[]>const groupsByCustom = groupBy(
items,
(item, index) => (item ? item.group : "unknown"),
(item, index) => (item ? item.name.toUpperCase() : "N/A")
);Mapwise includes null and undefined items by default. This means that all data—including nullish values—will appear in your results. To filter out any nullish items and keys, pass the option { excludeNullish: true }:
const cleanedMap = keyBy(items, "id", { excludeNullish: true });
const cleanedGroups = groupBy(items, "group", { excludeNullish: true });Note: When working with arrays that might contain null or undefined values, using property‑based key extraction without { excludeNullish: true } is disallowed by TypeScript to ensure safety. If you need to handle such cases explicitly, use a function‑based key extractor and manage nullish values within your callback.
bun testThis project is open source. See the LICENSE file for details.