@pawells/typescript-common
v3.0.5
Published
Shared TypeScript utility library
Maintainers
Readme
TypeScript Common Utility Library
Description
General-purpose TypeScript utility library organized into seven domain modules and four standalone modules. All functions are pure, strongly typed, and tree-shakeable via a single public barrel export.
Domain modules: array, enum, error, function, object, string, time
Standalone modules: LRU cache, JSON sanitization, Zod schemas, async retry with exponential backoff
The package is ESM-only, targets Node.js >= 22, and ships with full TypeScript declarations and source maps.
Requirements
- Node.js: >= 22.x
- TypeScript: >= 6.x
- Module system: ESM (
"type": "module"— CommonJS is not supported) - Peer dependencies:
zod>= 4.4.3 (required byzod-utilexports; import from'zod/v4')
Installation
npm install @pawells/typescript-common
# or
yarn add @pawells/typescript-commonQuick Start
import {
ArrayChunk,
ArrayPartition,
ObjectPick,
ObjectMerge,
CamelCase,
IsBlankString,
EnumValues,
BaseError,
GetErrorMessage,
Debounce,
WithRetry,
ElapsedTime,
Stopwatch,
LRUCache,
} from '@pawells/typescript-common';
// --- Array ---
ArrayChunk([1, 2, 3, 4, 5], 2);
// → [[1, 2], [3, 4], [5]]
const [evens, odds] = ArrayPartition([1, 2, 3, 4], (n) => n % 2 === 0);
// evens → [2, 4], odds → [1, 3]
// --- Object ---
ObjectPick({ a: 1, b: 2, c: 3 }, ['a', 'c']);
// → { a: 1, c: 3 }
// --- String ---
CamelCase('hello-world'); // → 'helloWorld'
IsBlankString(' '); // → true
// --- Function ---
const debouncedSave = Debounce(save, 300);
debouncedSave(); // fires after 300 ms of silence
debouncedSave.cancel(); // cancels any pending invocation
// --- Retry ---
const data = await WithRetry(() => fetchFromApi(), {
maxRetries: 3,
initialDelay: 500,
});
// --- Time ---
const sw = new Stopwatch();
sw.start();
// ... work ...
const elapsed = sw.stop();
console.log(elapsed.format('short')); // e.g. '1s 234ms'
// --- LRU Cache ---
const cache = new LRUCache<string, number>(100);
cache.set('key', 42);
cache.get('key'); // → 42API Reference
All symbols are re-exported from the single package entry point @pawells/typescript-common. There are no supported deep import paths.
Array
Functions for transforming, filtering, and querying arrays.
| Symbol | Kind | Description |
| --------------------------------------------------------------- | --------------- | -------------------------------------------------------------------------------------------------------- |
| ArrayChunk<T>(array, size) | function | Splits an array into sub-arrays of size. Returns [] for null/undefined input or non-positive size. |
| ArrayCompact<T>(array) | function | Removes null and undefined elements, narrowing the return type to T[]. |
| ArrayContains<T>(array, predicate) | function | Returns true if any element satisfies the predicate. |
| ArrayCountBy<T, K>(array, keyFn) | function | Groups elements by key and returns a count map. |
| ArrayDifference<T>(a, b, options?) | function | Returns elements in a that are not in b. Supports custom comparator, deep equality, or key function. |
| ArrayElement<A> | type | Extracts the element type of an array type: TArrayElement<string[]> → string. |
| ArrayFilter<T>(array, filter, options?) | function | Filters array elements against a partial filter criteria object. |
| ArrayFlatten<T>(array, depth?) | function | Recursively flattens a nested array to the given depth (default: Infinity). |
| ArrayGroupBy<T, K>(array, keyFn) | function | Groups elements by a derived key, returning a Record<K, T[]>. |
| ArrayIntersection<T>(a, b, options?) | function | Returns elements present in both arrays. Supports comparator, deep equality, or key function. |
| ArrayPartition<T>(array, predicate) | function | Splits into [passing, failing] — a typed tuple. |
| ArrayRange(start, end, step?) | function | Generates a numeric range array. |
| ArraySample<T>(array) / ArraySample<T>(array, n) | function | Returns one random element or n random elements without replacement. |
| ArrayShuffle<T>(array, random?) | function | Returns a new array with elements in random order (Fisher-Yates). |
| ArraySortBy<T>(array, keyFn, order?) | function | Returns a sorted copy using a key extractor; order defaults to 'asc'. |
| ArrayZip<T>(...arrays) | function | Zips multiple arrays into an array of tuples. |
| Unique<T>(array) | function | Removes duplicate elements using strict equality. |
| FilteredIterator<TObject, TArgs>(iterator, args?, validator?) | async generator | Async generator that filters an async iterable by optional criteria object and/or predicate. |
| TPredicate<T> | type | (value: T) => boolean |
| TTransform<TInput, TOutput> | type | (input: TInput) => TOutput |
| TComparator<T> | type | (a: T, b: T) => number |
| TEqualityComparator<T> | type | (a: T, b: T) => boolean |
| TArrayComparisonOptions<T> | type | Discriminated union for array comparison strategy: comparator, useDeepEqual, or keyFn. |
Enum
Type-safe helpers for querying and coercing TypeScript enum members.
| Symbol | Kind | Description |
| -------------------------------------- | -------- | ---------------------------------------------------------------------------------- |
| EnumEntries<T>(e) | function | Returns [key, value] pairs for all enum members, filtering reverse-mapping keys. |
| EnumKeyByValue<T>(e, value) | function | Looks up the key name for a given enum value; returns undefined if not found. |
| EnumKeys<O>(obj) | function | Returns the string keys of an enum, filtering out numeric reverse-mapping keys. |
| EnumSafeValue<T>(e, value, fallback) | function | Returns value if it is a valid enum member, otherwise fallback. |
| EnumValues<TEnum>(e) | function | Returns the values of an enum as a typed array. |
| ValidateEnumValue<T>(e, value) | function | Returns true if value is a member of the enum. |
| TEnumValue | type | string \| number |
| TEnumType | type | Record<string, TEnumValue> |
Error
Custom error base class and safe extraction utilities.
| Symbol | Kind | Description |
| --------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| BaseError<TMetadata> | class | Extends Error with a Code string, a typed Metadata bag, and a prototype-chain fix for correct instanceof checks after transpilation. All custom errors should extend BaseError. |
| TErrorMetadata | type | { code?: string; cause?: Error } |
| AssertErrorMetadata(metadata) | function | Asserts (throws via Zod) that metadata conforms to TErrorMetadata. |
| ValidateErrorMetadata(metadata) | function | Returns true if metadata conforms to TErrorMetadata, false otherwise. |
| GetErrorMessage(error) | function | Returns error.message for Error instances; String(error) for everything else. Safe to call in catch blocks with unknown. |
| GetErrorStack(error) | function | Returns error.stack for Error instances when defined; undefined otherwise. |
Function
Higher-order utilities for controlling function execution.
| Symbol | Kind | Description |
| --------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| Compose(...fns) | function | Right-to-left function composition. Up to five type-safe overloads; falls back to untyped for more. |
| Debounce<T>(fn, wait) | function | Returns a debounced function that delays invocation until wait ms have passed since the last call. The returned function has a .cancel() method. |
| Memoize<T>(fn, resolver?) | function | Returns a memoized function that caches results by arguments. Accepts an optional custom cache-key resolver. |
| Once<T>(fn) | function | Returns a function that calls fn only on the first invocation; subsequent calls return the cached result. |
| Pipe(...fns) | function | Left-to-right function composition. Up to five type-safe overloads. |
| Sleep(ms) | function | Returns a Promise<void> that resolves after ms milliseconds. |
| Throttle<T>(fn, limit) | function | Returns a throttled function that fires at most once per limit ms. The returned function has a .cancel() method. |
| TAnyFunction | type | (...args: any[]) => any |
| TAsyncFunction<T> | type | (...args: any[]) => Promise<T> |
| TConstructorFunction<T> | type | new (...args: never[]) => T |
Object
Utilities for cloning, diffing, picking, merging, hashing, and filtering plain objects.
| Symbol | Kind | Description |
| ------------------------------------------------------ | --------- | ----------------------------------------------------------------------------------------------------- |
| CreateCircularReferenceDetector() | function | Returns a detector object that tracks visited references to prevent circular-reference attacks. |
| CreateJsonCircularReplacer() | function | Returns a JSON.stringify replacer that replaces circular references with '[Circular]'. |
| FilterDangerousKeys<T>(obj) | function | Removes keys that could enable prototype pollution (__proto__, constructor, prototype). |
| FilterObject<T>(obj, predicate) | function | Returns a Partial<T> containing only the properties for which predicate returns true. |
| IsInputSafe(input, maxLength?) | function | Returns true if input passes basic safety checks (no null-byte injection, within length limit). |
| IsObject(item) | function | Type guard — returns true if item is a plain object (not null, not an array). |
| IsPropertyKeySafe(key) | function | Returns true if key is safe to use as a property name (no prototype-pollution risk). |
| IsPropertyPathSafe(path) | function | Returns true if every segment of a dot-notation path is safe. |
| ObjectClone<T>(obj) | function | Deep-clones a value using structured clone (falls back to JSON round-trip). |
| ObjectDiff(a, b) | function | Returns an IObjectDiffResult describing added, removed, and changed keys. |
| ObjectEquals(a, b) | function | Deep structural equality check. |
| ObjectFilter<T>(object, filter, options?) | function | Returns true if object matches all key/value pairs in filter. |
| ObjectFilterCached<T>(options?) | function | Returns a cached async filter function that reuses compiled filter predicates. |
| ObjectFlatten(obj, separator?) | function | Flattens a nested object to dot-notation keys. |
| ObjectFromKeyValuePairs<T>(entries) | function | Constructs a Record<string, T> from [key, value] pairs. |
| ObjectGetPropertyByPath<T>(obj, path, defaultValue?) | function | Reads a nested property by dot-notation path. Returns defaultValue (or undefined) on missing. |
| ObjectHash(obj, hashFunction?) | function | Produces a stable deterministic hash string for a plain object. |
| ObjectHasCircularReference(obj) | function | Returns true if obj contains at least one circular reference. |
| ObjectInvert<T>(obj) | function | Swaps keys and values, returning a new object. |
| ObjectMapCached<T>(options?) | function | Returns a cached async map function that reuses compiled property mappers. |
| ObjectMerge<T>(target, source) | function | Shallow-merges source into target, returning target. |
| ObjectOmit<T, K>(obj, keys) | function | Returns a copy of obj with the specified keys removed. |
| ObjectPick<T, K>(obj, keys) | function | Returns a new object containing only the specified keys. |
| ObjectSetPropertyByPath<T>(obj, path, value) | function | Sets a nested property by dot-notation path, creating intermediate objects as needed. |
| ObjectSortKeys<T>(object) | function | Returns a copy of object with keys sorted alphabetically. |
| ObjectToKeyValuePairs<T>(obj) | function | Converts a Record<string, T> to [key, value] pairs. |
| SanitizePropertyKey(key) | function | Returns a safe version of key, or null if it cannot be sanitized. |
| TransformObject<TInput, TOutput>(obj, transformer) | function | Applies a transformation function to an object, returning a new object. |
| MapObject<T>(obj, mapper) | function | Maps each property of obj through mapper, returning a new Record. |
| IObjectDiffResult | interface | { added: string[]; removed: string[]; changed: string[] } |
| IObjectFilterOptions | interface | Options for ObjectFilter: partial, caseSensitive. |
| ICachedObjectFilterOptions | interface | Options for ObjectFilterCached: cacheSize, ttl. |
| ICachedObjectMapOptions | interface | Options for ObjectMapCached: cacheSize, ttl. |
| ICircularReferenceDetector | interface | Exposes check(value) and release(value) for circular-reference tracking. |
| TPropertyMapper<T> | type | (value: T[K], key: K, obj: T) => unknown |
| TPropertyFilter<T> | type | (value: T[K], key: K, obj: T) => boolean |
String
Case conversion, formatting, transformation, validation, and comparison utilities.
| Symbol | Kind | Description |
| ------------------------------------------- | -------- | ----------------------------------------------------------------------------------------------- |
| CamelCase(value) | function | Converts a string to camelCase. |
| Capitalize(value) | function | Uppercases the first character and lowercases the rest. |
| CountOccurrences(str, substr) | function | Counts non-overlapping occurrences of substr in str. |
| EscapeHTML(str) | function | Replaces &, <, >, ", and ' with HTML entities. |
| EscapeNewlines(s) | function | Replaces literal newline characters with \n. |
| FormatString(template, params) | function | Interpolates named or positional placeholders in a template string. |
| IsBlankString(value) | function | Returns true if the string is empty or contains only whitespace. |
| IsHexString(value) | function | Returns true if the string is a valid hexadecimal string. |
| KebabCase(value) | function | Converts a string to kebab-case. |
| PadString(str, length, char?, padEnd?) | function | Pads str to length with char on the start or end. |
| PascalCase(value) | function | Converts a string to PascalCase. |
| Pluralize(word, count, plural?) | function | Returns the singular or plural form of a word based on count. |
| ReverseString(input) | function | Reverses the characters in a string. |
| ScreamingSnakeCase(value) | function | Converts a string to SCREAMING_SNAKE_CASE. |
| Slugify(input) | function | Converts a string to a URL-safe slug (lowercase, hyphens, no special characters). |
| SnakeCase(value) | function | Converts a string to snake_case. |
| StripHTML(str) | function | Removes all HTML tags from a string. |
| StringEquals(a, b, caseInsensitive?) | function | Compares two strings for equality, optionally case-insensitively. |
| TruncateString(str, maxLength, ellipsis?) | function | Truncates str to maxLength characters, appending ellipsis (default '...') if truncated. |
| WordCount(str) | function | Returns the number of whitespace-delimited words in str. |
| TCaseConverter | type | (value: string) => string |
| TFormatArgs | type | TFormatValue[] |
| TFormatParams | type | Record<string, TFormatValue> |
| TFormatValue | type | string \| number \| boolean \| null \| undefined |
| TStringFormatter | type | (value: string, ...params: unknown[]) => string |
| TStringPredicate | type | (value: string) => boolean |
| TStringTransformer | type | (input: string) => string |
| TStringValidator | type | (value: string) => boolean |
Time
Value-objects and classes for measuring and formatting durations.
| Symbol | Kind | Description |
| ------------------------------------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| ElapsedTime | class | Immutable value-object representing a duration in milliseconds. Provides format(preset) and toComponents() methods. |
| FormatElapsedTime(milliseconds, options?) | function | Formats a raw millisecond count as a human-readable duration string. |
| Stopwatch | class | Records timestamped events: start(), stop(), pause(), resume(), lap(), and reset(). Returns ElapsedTime instances from timing methods. |
| StopwatchEntry | class | Represents a single timestamped stopwatch event (label, elapsed, timestamp). |
| StopwatchError | class | Thrown by Stopwatch when operations are called in an invalid state (e.g., stopping a stopped watch). |
| ITimeElapsedFormatOptions | interface | Configuration for ElapsedTime.format(): unit labels, format preset, and separator. |
| ITimeUnitValue | interface | { unit: TTimeUnit; value: number } — a single time unit with its numeric value. |
| IUnitLabelMap | interface | Maps each TTimeUnit to a singular and plural label string or function. |
| TTimeElapsedFormats | type | 'concise' \| 'short' \| 'medium' \| 'long' \| 'mostSignificant' \| 'time' \| 'timeWithSeconds' |
| TTimeUnit | type | 'week' \| 'day' \| 'hour' \| 'minute' \| 'second' \| 'millisecond' |
LRU Cache (standalone)
| Symbol | Kind | Description |
| ---------------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| LRUCache<K, V> | class | Fixed-capacity Least Recently Used cache. Both get() and set() update recency order. Evicts the least recently used entry when capacity is reached. Do not cache sensitive values such as tokens or PII. |
JSON Sanitization (standalone)
| Symbol | Kind | Description |
| ---------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| SanitizeJsonSchema(schema) | function | Recursively removes all keys that begin with $ from a plain object. Designed for stripping JSON Schema metadata before storage (e.g., MongoDB). Returns Record<string, unknown>. |
Zod Utilities (standalone)
All schemas use zod v4 and must be imported with import ... from '@pawells/typescript-common' (not directly from 'zod/v4').
| Symbol | Kind | Description |
| -------------------------- | ----- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| OBJECT_ID_SCHEMA | const | Zod schema that validates a 24-character hexadecimal MongoDB ObjectId string. |
| TObjectId | type | z.infer<typeof OBJECT_ID_SCHEMA> |
| SEMVER_SCHEMA | const | Zod schema that validates and transforms a semver string into a SemVer instance. |
| ZOD_OBJECT_SCHEMA | const | Zod schema that validates a value is a ZodObject instance. |
| TZodObjectSchema | type | z.infer<typeof ZOD_OBJECT_SCHEMA> |
| JSON_SERIALIZABLE_SCHEMA | const | Recursive Zod schema accepting any JSON-serializable value. |
| TJSONSerializable | type | string \| number \| boolean \| null \| TJSONSerializable[] \| { [key: string]: TJSONSerializable } |
| JSON_OBJECT_SCHEMA | const | Zod schema for a Record<string, TJSONSerializable>. |
| JSON_DATE_SCHEMA | const | Zod schema that parses an ISO date string into a Date. Does not reject Invalid Date — chain .refine(d => !isNaN(d.getTime())) for strict validation. |
Retry (standalone)
| Symbol | Kind | Description |
| --------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------- |
| WithRetry<T>(fn, config?) | function | Wraps an async function with exponential backoff and ±20% jitter. Default: 3 retries, 1 s initial delay, 30 s cap, ×2 multiplier. |
| IRetryConfig | interface | Options: maxRetries, initialDelay, maxDelay, backoffMultiplier, onError (return false to abort early). |
License
MIT — See LICENSE for details.
