@lewishowles/helpers
| Install | |
|---|---|
npm install @lewishowles/helpers |
|
| Latest Version: | 3.0.0 |
| Vue: | 3 |
| License: | MIT |
| Last Updated: | Oct 19, 2026 |
| Links: | GitHub · npm |
Helpers
A library of gorgeous Javascript methods to make working with—and validating—data quicker and less error-prone, letting the developer concentrate on the fun stuff.
Installation
npm install @lewishowles/helpers
The package is ESM-only and requires Node.js 24 or newer. The Vue helpers need Vue 3, version 3.5.39 or later. Vue is an optional peer dependency, so you only need to install it if you use them.
Importing
Import helpers from the root package:
import { getNextIndex } from "@lewishowles/helpers";
Helpers are also grouped by type when you want narrower imports:
import { getNextIndex } from "@lewishowles/helpers/array";
Category subpaths are array, date, form, general, number, object, string, and url. Import Vue helpers from @lewishowles/helpers/vue; they are not exported from the root package.
Array
arrayLength(array: any[])
Determine the number of items in the given array.
Parameters
array{any[]}— The array to measure.
Returns
{number} — The number of items, or zero for non-arrays.
If the provided input is not an array, returns 0.
Example
arrayLength(["A", "B", "C", "D"]); // 4
arrayLength([]); // 0
arrayLength(undefined); // 0
chunk(array: any[], chunkSize: number)
Split an array into chunks of a specified size.
Parameters
array{any[]}— The array to split into chunks.chunkSize{number}— The number of items to include in each chunk.
Returns
{any[][]} — The array split into chunks, or an empty array when the size is not a
positive whole number.
Example
chunk([1, 2, 3], 2); // [[1, 2], [3]]
chunk([1, 2, 3], 1); // [[1], [2], [3]]
chunk([1, 2, 3], 5); // [[1, 2, 3]]
chunk([1, 2, 3], 0); // []
compact(array: any[])
Remove falsy values from the given array, including 0, false, "",
null, undefined, and NaN. Use array.filter(isDefined) to remove only
null and undefined.
Parameters
array{any[]}— The array to remove falsy values from.
Returns
{any[]} — A new array containing the truthy items.
Example
compact([0, 1, false, 2, "", 3]); // [1, 2, 3]
compact([true, true, true]); // [true, true, true]
const values = [0, false, "", null, undefined, NaN, "a"];
compact(values); // ["a"]
values.filter(isDefined); // [0, false, "", NaN, "a"]
countBy(array: object[], property: string)
Count the occurrences in array of each distinct value at property.
Supports dot-path notation for nested properties.
Parameters
array{object[]}— The array of objects to count.property{string}— The property path to count items by. Dot paths are supported.
Returns
{object} — An object mapping each resolved value to its count.
Items where property resolves to undefined are counted under the key
"undefined". All keys, including built-in property names such as
__proto__, are own, enumerable properties on an ordinary object.
Example
countBy([{ type: "a" }, { type: "b" }, { type: "a" }], "type");
// { a: 2, b: 1 }
countBy(
[{ address: { city: "York" } }, { address: { city: "Leeds" } }, { address: { city: "York" } }],
"address.city",
);
// { York: 2, Leeds: 1 }
ensureArray(maybeArray: any)
Ensure that maybeArray is an array.
Parameters
maybeArray{any}— The value to return as an array.
Returns
{any[]} — The original array or a new array containing the value.
Arrays are returned unchanged. Any non-array value is returned as a single-item array.
Note that null and undefined are preserved as values, returning [null]
and [undefined]. Combine with compact when falsy values should be
removed.
Example
ensureArray(["one", "two"]); // ["one", "two"]
ensureArray("one"); // ["one"]
ensureArray({ key: "value" }); // [{ key: "value" }]
ensureArray(null); // [null]
ensureArray(undefined); // [undefined]
firstDefined(array: any[])
Returns the first element in array that is not undefined. A null item
counts as a value, so it is returned when no other value comes before it. Use
array.find(isDefined) to skip null as well.
Parameters
array{any[]}— The array to search.
Returns
{any} — The first defined item, or undefined when none exists.
Example
firstDefined(["a", "b"]); // "a"
firstDefined([undefined, undefined, "c", "d"]); // "c"
firstDefined([undefined, null, 1]); // null
firstDefined([]); // undefined
firstWhere(array: any[], matcher: object): any
Return the first item in array that matches the given predicate function or
filter object. Returns undefined when no item matches or the input is
empty.
Parameters
array{any[]}— The array to search.matcher{function|object}— A predicate called with(item, index, array)that returns a truthy value, or an object of key-value pairs to match with strict equality. Object keys support dot paths, and every pair must match.
Returns
{any} — The first matching item, or undefined when none matches.
Example
firstWhere(users, (user) => user.active);
firstWhere(users, { role: "admin", active: true });
firstWhere(orders, { "customer.city": "York" });
getNextIndex(index: number, reference: any[], { reverse: boolean = false, wrap: boolean = false })
Given a starting index, determine the next available index in the
reference array.
Parameters
index{number}— The whole-number index to move from.reference{any[]}— The array that defines the valid index range.options{object}— How to move at the ends of the array.[options.reverse=false]{boolean}— Whether to find the previous index instead of the next index.[options.wrap=false]{boolean}— Whether to wrap around when moving beyond either end of the array.
Returns
{number} — The adjacent index, clamped or wrapped as requested.
An index outside the reference array is clamped unless wrapping is requested.
A non-whole index, or a reference that is not a non-empty array, returns 0.
Example
getNextIndex(3, ["A", "B", "C", "D"]); // 3
getNextIndex(3, ["A", "B", "C", "D"], { wrap: true }); // 0
getNextIndex(3, ["A", "B", "C", "D"], { reverse: true }); // 2
getNextIndex(-2, ["A", "B", "C"], { reverse: true, wrap: true }); // 0
groupBy(array: object[], property: string)
Group the given array of objects into sub-arrays keyed by the value at
property. Supports dot-path notation for nested properties.
Parameters
array{object[]}— The array of objects to group.property{string}— The property path to group items by.
Returns
{object} — An object mapping each resolved value to its items.
Items where property resolves to undefined are grouped under the key
"undefined". All keys, including built-in property names such as
__proto__, are own, enumerable properties on an ordinary object.
Example
groupBy(
[
{ type: "a", val: 1 },
{ type: "b", val: 2 },
{ type: "a", val: 3 },
],
"type",
);
// { a: [{ type: "a", val: 1 }, { type: "a", val: 3 }], b: [{ type: "b", val: 2 }] }
groupBy(
[{ addr: { city: "York" } }, { addr: { city: "York" } }, { addr: { city: "Leeds" } }],
"addr.city",
);
// { York: [{ addr: { city: "York" } }, { addr: { city: "York" } }], Leeds: [{ addr: { city: "Leeds" } }] }
head(array: any[])
Returns the first element in array.
Parameters
array{any[]}— The array to read from.
Returns
{any} — The first item, or undefined when the array is empty or invalid.
Example
head(["a", "b"]); // "a"
head([]); // undefined
isNonEmptyArray(variable: any[])
Determines whether the given variable is both an array and has at least one
item.
Parameters
variable{any[]}— The value to check.
Returns
{boolean} — Whether the value is a non-empty array.
Example
isNonEmptyArray(["A", "B", "C", "D"]); // true
isNonEmptyArray([]); // false
isNonEmptyArray("string"); // false
lastDefined(array: any[])
Returns the last element in array that is not undefined. A null item
counts as a value, so it is returned when no other value comes after it. Use
array.findLast(isDefined) to skip null as well.
Parameters
array{any[]}— The array to search.
Returns
{any} — The last defined item, or undefined when none exists.
Example
lastDefined(["a", "b"]); // "b"
lastDefined(["a", "b", undefined, undefined]); // "b"
lastDefined([1, null, undefined]); // null
lastDefined([]); // undefined
moveItem(array: any[], fromIndex: number, toIndex: number)
Move an item to a new position, returning a new array and leaving the original untouched.
Parameters
array{any[]}— The array containing the item to move.fromIndex{number}— The index of the item to move.toIndex{number}— The index to move the item to.
Returns
{any[]} — A new array with the item moved, or a copy for invalid indices.
toIndex is read after the item has been removed, matching how drag-and-drop
libraries report a drop. fromIndex must point at an existing item,
otherwise the array is returned unchanged; toIndex is clamped into range.
Example
moveItem(["a", "b", "c", "d"], 1, 3); // ["a", "c", "d", "b"]
moveItem(["a", "b", "c", "d"], 3, 1); // ["a", "d", "b", "c"]
moveItem(["a", "b", "c", "d"], 0, 3); // ["b", "c", "d", "a"]
partition(array: any[], predicate: function)
Split an array into two arrays based on a predicate. Returns a tuple of [matching[], nonMatching[]].
Parameters
array{any[]}— The array to split.predicate{function}— The function used to decide which output array receives each item.
Returns
{any[][]} — A pair containing matching items, then non-matching items.
Example
partition([1, 2, 3, 4, 5], (n) => n % 2 === 0); // [[2, 4], [1, 3, 5]]
partition([], () => true); // [[], []]
pluck(array: any[], property: string)
Retrieve an array of the property value from each of the objects found in
array.
Parameters
array{any[]}— The array of objects to read from.property{string}— The direct property key to pluck from each object.
Returns
{any[]} — The property values from object items in their original order.
Any non-objects in array are ignored. Objects that don't have the given
property yield undefined in the result. Empty or invalid input returns
[].
Note: property is a direct key only, and dot-path notation is not yet
supported. Use getPathValue for nested access.
Example
pluck([{ fruit: "apple" }, { fruit: "banana" }], "fruit"); // ["apple", "banana"]
pluck([{ fruit: "apple" }, { fruit: "banana" }], "colour"); // [undefined, undefined]
pluck([{ fruit: "apple" }, "not an object"], "fruit"); // ["apple"]
pluck([], "property"); // []
range(start: number, end?: number, step?: number)
Generate a numeric array from start to end, both inclusive. When called
with a single argument, start is treated as end and the range begins at
0. Direction is inferred automatically when start > end and no step is
given; an explicit step overrides it. A zero step returns an empty array.
Parameters
start{number}— The first number in the range, or the end value when called with one argument.end{number}— The final number to include in the range.step{number}— The amount to change by between each number.
Returns
{number[]} — The inclusive range, or an empty array for invalid inputs.
Example
range(5); // [0, 1, 2, 3, 4, 5]
range(1, 5); // [1, 2, 3, 4, 5]
range(0, 10, 2); // [0, 2, 4, 6, 8, 10]
range(5, 0); // [5, 4, 3, 2, 1, 0]
range(5, 0, -1); // [5, 4, 3, 2, 1, 0]
rankByMatch(array: any[], query: string, getLabel?: function): any[]
Return a new array of items with labels containing the trimmed query, ignoring case. Shorter labels come first, then labels with an earlier match. Items tied on both remain in their original order. Non-string labels are skipped, and an invalid array, query or label function returns an empty array. Accents are not folded.
Parameters
array{any[]}— The items to search. The input array is not changed.query{string}— The search text, with surrounding whitespace ignored.[getLabel]{function}— Return an item's label. When omitted, the item itself is used.
Returns
{any[]} — The matching items in ranked order, or an empty array for invalid input.
Example
rankByMatch(["Blueberry", "Berry", "Blackberry"], "berry"); // ["Berry", "Blueberry", "Blackberry"]
rankByMatch([{ name: "Blueberry" }, { name: "Berry" }], "berry", (item) => item.name);
sortByProperty(array: any[], criteria: object[])
Returns a new array containing the array of objects, sorted by the value at
property, with optional direction. When an array of criteria objects is
passed, sorts by each criterion in order, using the first non-zero
comparison.
Parameters
array{any[]}— The array of objects to sort.property{string}— The property path to sort by.options{object}— The direction for a single-property sort.[options.ascending=true]{boolean}— Whether to sort from lowest to highest.criteria{object[]}— An array of criteria objects to sort by, in priority order.criteria[].property{string}— The property path to sort by.criteria[].ascending{boolean}— Whether to sort from lowest to highest.
Returns
{any[]} — A sorted copy, or the original array for invalid criteria.
Example
sortByProperty([{ name: "Lewis" }, { name: "Alice" }], "name"); // [{ name: "Alice" }, { name: "Lewis" }]
sortByProperty([{ name: "Lewis" }, { name: "Alice" }], "name", { ascending: false }); // [{ name: "Lewis" }, { name: "Alice" }]
sortByProperty(
[
{ last: "Smith", first: "Alice" },
{ last: "Jones", first: "Bob" },
],
[
{ property: "last", ascending: true },
{ property: "first", ascending: true },
],
); // [{ last: "Jones", first: "Bob" }, { last: "Smith", first: "Alice" }]
tail(array: any[])
Returns the last element in array.
Parameters
array{any[]}— The array to read from.
Returns
{any} — The last item, or undefined when the array is empty or invalid.
Example
tail(["a", "b"]); // "b"
tail([]); // undefined
toggleItem(array: any[], item: any, comparator?: ((a: any, b: any) => boolean) | string)
Add an item to an array if it is not present, or remove all occurrences of it if it is. Returns a new array and does not mutate the original. Non-array input returns an empty array. With a key comparator, a null or undefined item or entry counts as lacking the key, so it matches any value without that key.
Parameters
array{any[]}— The array to toggle the item within.item{any}— The item to add or remove.comparator{((a: any, b: any) => boolean) | string}— The matching function or object key used to compare items.
Returns
{any[]} — A new array with matching items removed or the item appended.
Example
toggleItem([], 1); // [1]
toggleItem([1, 2, 3], 2); // [1, 3]
toggleItem([1, 2, 3], 4); // [1, 2, 3, 4]
toggleItem([{ id: 1 }, { id: 2 }], { id: 1 }, "id"); // [{ id: 2 }]
unique(array: any[])
Safely reduce the provided array to those entries which are unique.
Parameters
array{any[]}— The array to reduce to unique entries.
Returns
{any[]} — A new array of unique values.
Example
unique([1, 2, 2, 3, 4, 4, 5]); // [1, 2, 3, 4, 5]
unique(["a", "b", "a", "c"]); // ["a", "b", "c"]
unique([]); // []
uniqueBy(array: object[], property: string)
Remove duplicate objects from an array based on a property value. Supports dot-path notation for nested properties. The first occurrence of each value is kept.
Parameters
array{object[]}— The array of objects to reduce.property{string}— The property path that identifies duplicate items.
Returns
{object[]} — A new array without repeated property values.
Items where the resolved value is undefined are treated as equal, with only
the first occurrence kept.
Example
uniqueBy(
[
{ id: 1, name: "A" },
{ id: 2, name: "B" },
{ id: 1, name: "C" },
],
"id",
);
// [{ id: 1, name: "A" }, { id: 2, name: "B" }]
uniqueBy(
[
{ address: { city: "London" } },
{ address: { city: "Paris" } },
{ address: { city: "London" } },
],
"address.city",
);
// [{ address: { city: "London" } }, { address: { city: "Paris" } }]
uniqueBy([{ id: 1 }, { id: 1 }, { id: 1 }], "id");
// [{ id: 1 }]
uniqueBy([], "id");
// []
Date
addToDate(value: any, amount: number, unit: "day" | "week" | "month" | "year", options?: object)
Shift a parseDate-compatible value by a calendar amount and unit, returning
a new Temporal value of the same precision as the input. Negative amounts
subtract; 0 returns an equivalent value for the same day.
Parameters
value{any}— The date value to shift.amount{number}— The integer amount to shift by. Negative values subtract.unit{("day"|"week"|"month"|"year")}— The calendar unit to shift by.options{object}— Per-call date helper options (passed through toparseDate).options.inputFormat{string}— The Day.js-style token format used when parsing non-ISO strings.
Returns
{object|null} — A shifted Temporal date, or null when the input cannot be shifted.
Temporal.Instant values return null because instants have no calendar and
cannot accept calendar-unit arithmetic. Anchor to a timezone first if you
need to shift an instant.
Example
addToDate("2026-07-06", 1, "day"); // Temporal.PlainDate 2026-07-07
addToDate("2026-07-06T10:15:30", -3, "day"); // Temporal.PlainDateTime 2026-07-03T10:15:30
addToDate("2026-07-06T10:00:00[Europe/London]", 2, "week"); // Temporal.ZonedDateTime 2026-07-20T10:00:00+01:00[Europe/London]
configureDateHelpers(config?: object)
Set project-wide defaults for date parsing and formatting.
Parameters
config{object}— The date helper defaults to merge into the active configuration.config.locale{string}— The BCP 47 locale used by Intl formatters.config.timeZone{string}— The timezone used when anchoring plain dates and date-times.config.inputFormat{string}— The Day.js-style token format used when parsing non-ISO strings.config.defaultFormat{string}— The named format used when formatting without a format argument.config.formats{object}— The named Day.js token or Intl format options available toformatDate.
Returns
{object} — A defensive copy of the updated date helper configuration.
Calling this helper with no arguments returns the current configuration.
Projects can override these defaults per helper call. The default locale is
en-GB, the default timezone is Europe/London, and token formats use
Day.js-style tokens such as DD/MM/YYYY.
The formats option is a map of named output formats. Each key is a name
that can be passed to formatDate as the format argument, and each value is
either a Day.js-style token string (e.g. "DD/MM/YYYY") or an
Intl.DateTimeFormatOptions object (e.g. { dateStyle: "medium" }). The
built-in named formats are date, dateTime, time, and shortDate.
Projects can override these or add their own, because formatDate looks up
the format name each time it is called. The defaultFormat option determines
which named format is used when formatDate is called with no format
argument.
Examples
configureDateHelpers({
locale: "en-US",
timeZone: "America/New_York",
inputFormat: "MM/DD/YYYY",
formats: {
shortDate: "MM/DD/YYYY",
fullDate: { year: "numeric", month: "long", day: "2-digit" },
},
defaultFormat: "fullDate",
});
// formatDate("22/06/2026") uses defaultFormat → "fullDate"
// formatDate("22/06/2026", "shortDate") uses the named format → "06/22/2026"
formatDate(value: any, format?: string|object, options?: object)
Format supported date input using a named configured format, a Day.js-style
token string, or Intl.DateTimeFormat options.
Parameters
value{any}— The date value to format.format{string | object}— The named format, Day.js token string, or Intl format options to use.options{object}— Per-call date helper options.options.locale{string}— The BCP 47 locale used by Intl formatters.options.timeZone{string}— The timezone used when anchoring plain dates and date-times.options.inputFormat{string}— The Day.js-style token format used when parsing non-ISO strings.options.defaultFormat{string}— The named format used whenformatis omitted.options.formats{object}— The named Day.js token or Intl format options available by key.
Returns
{string|null} — The formatted date, or null for an invalid date.
Example
formatDate("22/06/2026");
formatDate("22/06/2026", "shortDate");
formatDate("2026-06-22", { year: "numeric", month: "long", day: "2-digit" });
formatRelativeDate(value: any, relativeTo?: any, options?: object)
Show dates as 3 minutes ago or in 2 days.
Parameters
value{any}— The date value to format.relativeTo{any}— The date value to compare against.options{object}— Per-call date helper options.options.locale{string}— The BCP 47 locale used by the relative time formatter.options.timeZone{string}— The timezone used when anchoring plain dates and date-times.options.inputFormat{string}— The Day.js-style token format used when parsing non-ISO strings.
Returns
{string|null} — The relative date text, or null for an invalid date.
Example
formatRelativeDate("2026-06-22T09:59:00", "2026-06-22T10:00:00");
// "1 minute ago"
getDateHelpersConfig()
Get a defensive copy of the active date helper configuration. Useful when
building custom date helpers that should respect the same global defaults set
via configureDateHelpers.
Returns
{object} — A deep copy of the current date helper configuration.
Example
const config = getDateHelpersConfig();
// { locale: "en-GB", timeZone: "Europe/London", inputFormat: "DD/MM/YYYY", ... }
getDateParts(value: any, options?: object)
Convert a parseDate-compatible input into { year, month, day }, for use
with <input type="date">-style three-field date components. Instants and
zoned date-times are anchored to the configured or per-call timezone before
the calendar date is read.
Parameters
value{any}— The date value to convert.options{object}— Per-call date helper options.options.timeZone{string}— The timezone used when anchoring instants and zoned date-times.options.inputFormat{string}— The Day.js-style token format used when parsing non-ISO strings.
Returns
{object|null} — The year, month and day, or null for an invalid date.
Invalid or empty input returns null.
Example
getDateParts("2026-06-22"); // { year: 2026, month: 6, day: 22 }
getDateParts("2026-06-22T23:30:00Z", { timeZone: "Europe/London" });
// { year: 2026, month: 6, day: 23 }
getDateParts("not a date"); // null
getRelativeDateParts(value: any, relativeTo?: any, options?: object)
Convert two supported dates into relative date parts for use with
Intl.RelativeTimeFormat or custom UI rendering.
Parameters
value{any}— The date value to compare.relativeTo{any}— The date value to compare against.options{object}— Per-call date helper options.options.timeZone{string}— The timezone used when anchoring plain dates and date-times.options.inputFormat{string}— The Day.js-style token format used when parsing non-ISO strings.
Returns
{object|null} — The signed value and relative unit, or null for an invalid date.
Example
getRelativeDateParts("2026-06-22T10:00:00", "2026-06-22T10:01:00");
// { value: -1, unit: "minute" }
hasDateParts(parts: object)
Determine whether a { day, month, year } object has at least one non-empty
part. Empty strings, whitespace-only strings, null, and undefined count
as empty.
Parameters
parts{object}— The date parts to inspect.
Returns
{boolean} — Whether any supported date part is filled.
Example
hasDateParts({ day: "1", month: "", year: "" }); // true
hasDateParts({ day: "", month: "", year: "" }); // false
isTemporalDate(value: any, type?: string)
Check whether a value is a Temporal Instant, PlainDate, PlainDateTime,
or ZonedDateTime. An optional type restricts the check to one supported
Temporal type.
Parameters
value{any}— The value to inspect.type{string}— The optional Temporal type name to match.
Returns
{boolean} — Whether the value has a supported Temporal date tag.
Recognition uses Temporal's standard string tags, so values from another compatible Temporal implementation or module copy are supported. This is a type check for genuine Temporal values, not validation of untrusted objects that deliberately imitate those tags.
Example
isTemporalDate(Temporal.PlainDate.from("2026-06-22")); // true
isTemporalDate(value, "PlainDate");
parseDate(value: any, options?: object)
Convert Date, timestamp, Temporal, ISO/RFC 9557 string, configured
token-format string, or { year, month, day } parts object into a Temporal
date value.
Parameters
value{any}— The date value to parse.options{object}— Per-call date helper options.options.inputFormat{string}— The Day.js-style token format used when parsing non-ISO strings.
Returns
{object|null} — A supported Temporal date value, or null for invalid input.
Token strings use Day.js-style tokens such as DD/MM/YYYY. Invalid or empty
values return null. Parts objects are rejected (not clamped) when the month
or day is out of range, such as 30 February 2026.
Example
parseDate("2026-06-22"); // Temporal.PlainDate
parseDate("2026-06-22T10:15:30Z"); // Temporal.Instant
parseDate("22/06/2026 10:15", { inputFormat: "DD/MM/YYYY HH:mm" }); // Temporal.PlainDateTime
parseDate({ year: 2026, month: 6, day: 22 }); // Temporal.PlainDate
toDateFromParts(parts: object)
Convert <input type="date">-style three-field parts into a
Temporal.PlainDate. Parts carry no timezone information, so the result is
always a plain date; anchor it with toEpochMilliseconds/formatDate when
an instant is needed.
Parameters
parts{object}— The date parts to convert.parts.year{number|string}— The year.parts.month{number|string}— The month,1-indexed.parts.day{number|string}— The day of the month.
Returns
{Temporal.PlainDate|null} — The parsed plain date, or null for invalid parts.
Only a { year, month, day } plain object is accepted; strings, timestamps,
Date instances, and Temporal values are rejected. String parts must be
numeric. Missing, non-numeric, or out-of-range parts return null.
Example
toDateFromParts({ year: 2026, month: 6, day: 22 }); // Temporal.PlainDate
toDateFromParts({ year: 2026, month: 2, day: 30 }); // null
toEpochMilliseconds(value: any, options?: object)
Convert a supported date input into epoch milliseconds. Plain dates and plain date-times use the configured timezone.
Parameters
value{any}— The date value to convert.options{object}— Per-call date helper options.options.timeZone{string}— The timezone used when anchoring plain dates and date-times.options.inputFormat{string}— The Day.js-style token format used when parsing non-ISO strings.
Returns
{number|null} — Epoch milliseconds, or null for an invalid date.
Example
toEpochMilliseconds("22/06/2026");
toEpochMilliseconds("06/22/2026", { inputFormat: "MM/DD/YYYY", timeZone: "America/New_York" });
Form
validateField(fieldName: string, validationRules: object[], formData: object): Promise<ValidationResult>
Validate a field given its fieldName, the field's validationRules, and
the sum total formData.
Parameters
fieldName{string}— The name of the field to validate.validationRules{object[]}— The rules, schemas, or validation functions to apply.formData{object}— The current values of each form field.
Returns
{Promise<object>} — The field result: whether it is valid, its error messages, and whether
validation ran.
Returns { valid, errors, validated }. If input is invalid (missing field
name, rules, or form data), validated is false and the field is treated as
valid.
Available rules and properties include:
Single-field rules other than required and accepted pass when the field
has no value. Combine them with required or required_if when empty values
should fail.
required
[{ rule: "required", message: "Enter your name so we know what to call you" }]
Requires an answer. false counts as an answer; use accepted when a
checkbox must be ticked.
accepted
[{ rule: "accepted", message: "Accept the terms to continue" }]
Requires a checkbox to be ticked, such as one agreeing to terms. Only the
boolean true passes, so an unticked or missing checkbox fails even when the
field has no required rule.
email
[{ rule: "email", message: "We need an email address to set up your account" }]
Perform a minimal check to see if the value contains an @ symbol. More
complex verification isn't really necessary, and the only true way to test an
email address is through verification.
size
[{ rule: "size", size: 11, message: "Your phone number should be 11 digits long" }]
Ensure that the provided value has exactly size size. For strings, the
number of characters is used, for arrays, the length of the array, for
objects, the number of properties, for numbers, the number itself is used,
and for numeric strings the integer value of the string is used.
min
[{ rule: "min", min: 11, message: "Your phone number should be at least 11 digits long" }]
Ensure that the provided value has at least size min. Values are evaluated
as in the size rule.
max
[{ rule: "max", max: 11, message: "Your phone number should be no more than 11 digits long" }]
Ensure that the provided value has at most size max. Values are evaluated
as in the size rule.
between
[{ rule: "between", min: 5, max: 8, message: "Your post code should be between 5 and 8 characters" }]
Ensure that the provided value has a size between min and max. Values are
evaluated as in the size rule.
in
[{ rule: "in", options: ["a", "b", "c"], message: "Your choice should be a, b, or c" }]
Ensure that the given value is included within options.
not_in
[{ rule: "not_in", options: ["a", "b", "c"], message: "Your choice should not include a, b, or c" }]
Ensure that the given value is not included within options.
regexp
[{ rule: "regexp", regexp: /[abc]+/, message: "Your ID should only contain the letters a, b, and c" }]
Ensure that the provided value matches regexp.
valid_date
[{ rule: "valid_date", message: "Enter a complete date" }]
Validate { day, month, year } date-parts objects when the user has entered
at least one part. Empty or missing values pass so presence remains the job
of required and required_if.
custom
[{ rule: "custom", validate: (value, formData) => value > formData.startDate, message: "Your end date should be after your start date" }]
The escape hatch for any rule the declarative rules can't express, including
cross-field validation. validate receives the field's own value and the
complete formData, and should return a truthy value to pass. A custom
rule without a validate function always fails.
Standard Schema
Any object with a ~standard property (Zod, Valibot, ArkType schemas) is
detected and validated through the Standard
Schema interface. The
schema's ~standard.validate(value) is called, and any returned issues are
mapped to error strings. Schemas can return results synchronously or
asynchronously.
import { z } from "zod";
const schema = z.string().email("Enter a valid email address");
validateField("email", [schema], { email: "not-an-email" });
// { valid: false, errors: ["Enter a valid email address"], validated: true }
Schemas, object rules, and function shorthand can be freely mixed in the same rules array.
Function shorthand
[(value, formData) => value.includes("@") || "Enter a valid email address"]
A bare function in the rules array is a shorthand for custom validation
without a separate message property. The function receives the field's own
value and the complete formData, and its return value determines the
outcome:
| Return value | Result |
|---|---|
| Non-empty string | Single error — the string is the error message |
| Non-empty array of non-empty strings | Multiple errors — each string is a separate error message |
| Any other value | Valid — no error |
This mirrors the custom rule's (value, formData) signature, but inverts
the convention: instead of returning a boolean and reading the message from
the rule object, the function returns the error message(s) directly when
validation fails. Functions and object rules can be freely mixed in the same
rules array.
required_if
[{ rule: "required_if", field: "wantsNewsletter", value: true, message: "Enter an email address to receive the newsletter" }]
Requires an answer, but only when another field's value meets a condition. As
with required, false counts as an answer. When value is provided, the
condition is met when formData[field] strictly equals it. When value is
omitted, the condition is met when formData[field] has a value other than
false, so an unticked checkbox does not trigger the rule.
same
[{ rule: "same", field: "password", message: "Your passwords should match" }]
Ensure that the value matches the value of another field.
different
[{ rule: "different", field: "currentPassword", message: "Your new password should differ from your current one" }]
Ensure that the value differs from the value of another field.
Example
await validateField("username", [{ rule: "required", message: "Enter a username" }], {
username: "",
}); // { valid: false, errors: ["Enter a username"], validated: true }
await validateField("username", [{ rule: "required", message: "Enter a username" }], {
username: "jack_skellington",
}); // { valid: true, errors: [], validated: true }
await validateField(
"email",
[
{ rule: "required", message: "Enter your email" },
(value) => value.includes("@") || "Enter a valid email address",
],
{ email: "not-an-email" },
); // { valid: false, errors: ["Enter a valid email address"], validated: true }
validateForm(fields: object, formData: object): Promise<{ valid, validated, results }>
Validate multiple fields at once, delegating to validateField for each
field's rules. Cross-field rules (same, different, required_if,
custom) work naturally because the full formData is passed through to
each field.
Parameters
fields{object}— A map of field names to validation rule arrays.formData{object}— The current values of each form field.
Returns
{Promise<object>} — The combined field results and overall validation status.
Returns { valid, validated, results }. If input is invalid (non-object
fields or formData), validated is false and the form is treated as
valid — the same convention as validateField.
The results object contains a validateField result for each field that
had a non-empty rules array. Fields with empty or non-array rules are skipped
and omitted from results. The overall valid is false only when a field
has valid: false. Fields with validated: false (skipped) don't make the
form invalid.
Example
await validateForm(
{
username: [{ rule: "required", message: "Enter a username" }],
email: [
{ rule: "required", message: "Enter your email" },
(value) => value.includes("@") || "Enter a valid email address",
],
},
{ username: "jack", email: "not-an-email" },
);
// {
// valid: false,
// validated: true,
// results: {
// username: { valid: true, errors: [], validated: true },
// email: { valid: false, errors: ["Enter a valid email address"], validated: true },
// },
// }
General
debounce(fn: function, delay?: number, options?: object)
Returns a debounced version of fn that waits until delay milliseconds
have passed without another call before running.
Parameters
fn{function}— The function to debounce.delay{number}— The delay in milliseconds before running the function.options{object}— Options controlling when the function runs.options.leading{boolean}— Whether to run on the first call in a debounce window.options.trailing{boolean}— Whether to run after calls stop.
Returns
{Function} — A function that delays calls, returns the most recent result when one is
available, and exposes .cancel() and .flush().
By default fn runs on the trailing edge, after calls stop, using the most
recent call's arguments and this. Set options.leading to also run on the
first call, or options.trailing: false to skip the trailing run; with both
false it never runs.
The returned function exposes .cancel() to discard a pending run and
.flush() to run it immediately and return its result. A non-function fn
returns a safe no-op, and an invalid delay is treated as 0.
Examples
const search = debounce(runSearch, 300);
const save = debounce(saveForm, 1000, { leading: true });
getFriendlyDisplay(variable: any)
Convert a given variable into a human-readable representation of its type.
Parameters
variable{any}— The value to describe.
Returns
{string | undefined} — A readable label, or undefined when no supported type matches.
Example
getFriendlyDisplay(["A", "B", "C", "D"]); // <array[4]>
getFriendlyDisplay([]); // <array[0]>
getFriendlyDisplay("hello"); // hello <string>
isDefined(value: any)
Determines whether the given value is neither null nor undefined.
Unlike a falsy check, this guard treats 0, "", and false as defined
values. Pass it to array.filter or array.find to skip both null and
undefined; firstDefined and lastDefined skip only undefined.
Parameters
value{any}— The value to check.
Returns
{boolean} — Whether the value is defined.
Example
isDefined("hello"); // true
isDefined(0); // true
isDefined(null); // false
isDefined(undefined); // false
isEqual(a: unknown, b: unknown)
Determine whether a and b are deeply equal. Primitives are compared with
SameValueZero semantics, so NaN is equal to NaN, and null/undefined
are not equal to each other. Arrays are equal when they share the same length
and every element is deeply equal in order. An array hole compares as
undefined. Plain objects are equal when they share the same set of
own-enumerable keys and every value is deeply equal, regardless of key order.
Anything else, including a type mismatch between the two values, or non-plain
objects such as Date, Map, Set, or class instances, is not equal unless
the two values are the same reference.
Parameters
a{unknown}— The first value to compare.b{unknown}— The second value to compare.
Returns
{boolean} — Whether the values are deeply equal.
Example
isEqual(NaN, NaN); // true
isEqual(null, undefined); // false
isEqual([1, { property: "value" }], [1, { property: "value" }]); // true
isEqual({ a: 1, b: 2 }, { b: 2, a: 1 }); // true
isFunction(variable: any)
Determines whether the given variable is a function.
Parameters
variable{any}— The value to check.
Returns
{boolean} — Whether the value is a function.
Example
isFunction(() => "Hello"); // true
isFunction("function"); // false
isFunction(5); // false
resolveOrFallback(promise: any, fallback: any | (() => any))
Resolves promise, returning its value, or fallback if it rejects. Always
returns a promise, even for synchronous inputs, for a consistent shape.
Parameters
promise{any}— The promise or value to resolve.fallback{any | function}— The fallback value, or function returning one, to use when resolution fails.
Returns
{Promise<any>} — A promise for the resolved value, or the fallback when resolution fails.
This is async/value recovery, not validation — see validateOrFallback for
keyword-based value checks.
If fallback is a function it is called lazily, only on rejection, and its
return value is used. A throwing fallback function propagates. Non-thenable
inputs resolve as-is, except null / undefined, which resolve to the
fallback.
Example
await resolveOrFallback(api.getSettings(), defaultSettings);
await resolveOrFallback(fetchRemote(), () => getCached());
settle(promises: any[])
Awaits an array of promises (or plain values) and reports every outcome,
mirroring Promise.allSettled. Returns a positional results array
alongside convenience values and errors arrays for common bulk-action
patterns.
Parameters
promises{any[]}— The promises or values to settle.
Returns
{Promise<object>} — The results for every item in order, plus the fulfilled values and
rejected errors.
Non-thenable values are treated as fulfilled and returned as-is — functions
are never invoked. To run functions, call them first:
settle(items.map(item => action(item))).
The results array includes every item in order, and each entry carries its
original index, so a failure can be mapped straight back to its input —
useful for bulk operations where you need to know exactly which calls failed.
values and errors exclude the other outcome's gaps, for the common
"everything that worked / failed" patterns.
Examples
const { results } = await settle(ids.map((id) => api.delete(id)));
const failedIds = results
.filter((result) => result.status === "rejected")
.map((result) => ids[result.index]);
const { values, errors, results } = await settle([Promise.resolve(1), Promise.reject("nope")]);
// values: [1]
// errors: ["nope"]
// results: [
// { status: "fulfilled", value: 1, index: 0 },
// { status: "rejected", reason: "nope", index: 1 },
// ]
const action = () => "called";
const { values } = await settle([7, action]); // values: [7, action]; action was not called
await settle([]); // { values: [], errors: [], results: [] }
await settle(null); // { values: [], errors: [], results: [] }
size(variable: any)
Determine the size of the given variable. For strings, the number of
characters is used; for numbers, the value itself; for arrays, the length;
for objects, the number of top-level properties. Returns 0 if no reasonable
size can be determined.
Parameters
variable{any}— The value to measure.
Returns
{number} — The size of the value, or 0 when no size can be determined.
Example
size("hello"); // 5
size(42); // 42
size([1, 2, 3]); // 3
size({ a: 1, b: 2 }); // 2
size(null); // 0
throttle(fn: function, delay?: number, options?: object)
Returns a throttled version of fn that runs at most once per delay
milliseconds.
Parameters
fn{function}— The function to throttle.delay{number}— The minimum delay in milliseconds between function runs.options{object}— Options controlling when the function runs.options.leading{boolean}— Whether to run at the start of a throttle window.options.trailing{boolean}— Whether to run at the end of a throttle window.
Returns
{Function} — A function that limits calls, returns the most recent result when one is
available, and exposes .cancel() and .flush().
By default fn runs immediately on the first call, then once more at the end
of the window if further calls arrived during it, using the latest arguments
and this. Set options.leading: false to skip the immediate run, or
options.trailing: false to skip the closing one; with both false it never
runs.
The returned function exposes .cancel() to discard a pending run and
.flush() to run it immediately and return its result. A non-function fn
returns a safe no-op, and an invalid delay is treated as 0.
Examples
window.addEventListener("scroll", throttle(onScroll, 100));
const save = throttle(saveForm, 500, { leading: false });
validateOrFallback(variable: any, comparison: function | string, fallback: any)
Apply comparison to the provided variable, returning variable if
true, and fallback if not.
Parameters
variable{any}— The value to validate.comparison{function | string}— The validation function or keyword to apply.fallback{any}— The value to return when validation fails.
Returns
{any} — The valid value, or the fallback.
comparison can be a function, or one of the keywords:
string: A string, including an empty stringboolean: Strictly true or falsenumber: A number, excluding NaN, based onisNumberfunction: A function, based onisFunctionarray: An array, including an empty arrayobject: An object, including an empty object
Example
validateOrFallback("value", "string", "fallback"); // "value"
validateOrFallback({}, isNonEmptyObject, null); // null
validateOrFallback(5, "number", 0); // 5
Number
clamp(value: number, minimum: number, maximum: number)
Ensure that the provided value is between minimum and maximum
(inclusive). If value is lower than minimum, minimum is returned. If
value is higher than maximum, maximum is returned.
Parameters
value{number}— The number to clamp.minimum{number}— The lowest allowed value.maximum{number}— The highest allowed value.
Returns
{number} — The value within the validated bounds.
A value that is not a number is treated as 0 before clamping.
Example
clamp(4); // 4
clamp(10, 0, 5); // 5
clamp(-15, 0, 5); // 0
clamp(NaN); // 0
isNumber(variable: any)
Determines whether the given variable is a number and not NaN. Infinity
and -Infinity count as numbers. Use isNumeric to check for a finite
number, including a numeric string.
Parameters
variable{any}— The value to check.
Returns
{boolean} — Whether the value is a number other than NaN.
Example
isNumber(4); // true
isNumber(Infinity); // true
isNumber(NaN); // false
isNumber("string"); // false
isNumeric(value: any)
Determines whether the given value is a finite number or a string
containing one. Surrounding spaces are allowed, but Infinity is rejected
whether it is passed as a number or a string.
Parameters
value{any}— The value to check.
Returns
{boolean} — Whether the value can be read as a finite number.
Example
isNumeric(4); // true
isNumeric(Infinity); // false
isNumeric("Infinity"); // false
isNumeric(" 12 "); // true
isNumeric(NaN); // false
isNumeric("string"); // false
isNumeric("10e3"); // true
isNumeric("5.6"); // true
round(value: number, decimals: number = 0)
Rounds the given value to the specified number of decimals. If decimals
is not provided, it defaults to 0.
Parameters
value{number}— The number to round.decimals{number}— A whole number of decimal places to keep. Negative values round to tens, hundreds, and larger places.
Returns
{number} — The rounded number.
Throws
{TypeError}— When either argument is not a number.{RangeError}— When either argument is not finite.{RangeError}— Whendecimalsis not a whole number.
Example
round(4.567); // 5
round(4.567, 2); // 4.57
round(4.567, 0); // 5
round(4.567, -1); // 0
toNullableNumber(value: any)
Coerces the given value to a number, returning null for an empty or
whitespace-only string, null, or undefined. Useful for form round-trips
where absent numeric fields should be null rather than 0 or NaN. Other
values are passed to Number() without validation, so text such as "12px"
becomes NaN. Check the value with isNumeric first to reject invalid or
infinite input.
Parameters
value{any}— The value to coerce.
Returns
{number|null} — The converted number, or null for an absent value.
Example
toNullableNumber("42"); // 42
toNullableNumber("12px"); // NaN
toNullableNumber(" "); // null
toNullableNumber("Infinity"); // Infinity
toNullableNumber(""); // null
toNullableNumber(null); // null
toNullableNumber(undefined); // null
toPercentage(value: any, total: any)
Calculates the percentage of value relative to total, returning 0 when
total is zero or falsy to avoid division by zero. Non-numeric inputs are
coerced; NaN or Infinity inputs return 0. The result is not clamped, so
a value exceeding total will produce a percentage above 100.
Parameters
value{any}— The value to convert to a percentage.total{any}— The total value that represents 100%.
Returns
{number} — The percentage, or zero when the inputs cannot produce a finite result.
Example
toPercentage(25, 100); // 25
toPercentage(1, 4); // 25
toPercentage(10, 0); // 0
toPercentage(10, null); // 0
Object
addProperty(object: object, key: string, value: any)
Add a shallow key / value pair to an object without overwriting any existing value. That is, only if that key isn't already present, or if its value is undefined or null.
Parameters
object{object}— The object to add the property to.key{string}— The property key to add.value{any}— The value to set when the key is missing or empty.
Returns
{object} — A copy with the property added, or an empty object for an invalid input.
Example
addProperty({ one: "One", two: "Two" }, "one", "Two"); // { one: "One", two: "Two" }
addProperty({ one: "One", two: "Two" }, "three", "Three"); // { one: "One", two: "Two", three: "Three" }
addProperty({ one: "One", two: null }, "two", "Two"); // { one: "One", two: "Two" }
deepCopy(value: any)
Returns a deep copy of value. Non-objects are returned unchanged.
Parameters
value{any}— The value to copy.
Returns
{any} — A deep copy of the value, or the original primitive or function.
Uses the built-in structuredClone where possible, so Date, Map, Set,
RegExp, typed arrays, and cyclic references are cloned correctly. For
values structuredClone cannot handle, such as objects containing functions,
it falls back to a recursive copy that copies functions by reference and
preserves cyclic references via a WeakMap.
Example
deepCopy({ key: "value" }); // { key: "value" }
deepCopy(["a", "b"]); // ["a", "b"]
deepCopy(new Date(0)); // a new Date with the same time
deepMerge(object: object)
Recursively merges two or more objects. The values of later objects override those of earlier objects.
Parameters
target{object}— The object to merge into.sources{object[]}— The source objects to merge from.
Returns
{object} — The recursively merged object.
Example
deepMerge({ key: "value" }, { value: "key" }); // { key: "value", value: "key" }
deepMerge({ key: "value", a: { b: 2 } }, { key: "modified", a: { c: 3 } }); // { key: "modified", a { b: 2, c: 3 }}
deepMergeWith(target: object, sources: array, options?: object)
Works like deepMerge, but lets you decide what happens when the same key
holds an array in both the target and a source.
Parameters
target{object}— The object to merge into.sources{object[]}— The source objects to merge from.options{object}— Merge behaviour.options.arrayStrategy{string}— How arrays are combined when both objects contain arrays at the same key.
Returns
{object} — The merged object without changing the inputs.
Set options.arrayStrategy to "replace" (the default) so the source array
wins, just like deepMerge; "concatenate" to join both arrays with target
items first; or "merge" to combine arrays position by position,
deep-merging plain objects at the same position.
Other values merge like deepMerge: objects merge recursively, class
instances stay intact, and the inputs are not changed. Sources are passed as
one array so options stays at the end.
Examples
deepMergeWith({ tags: ["a"] }, [{ tags: ["b"] }], { arrayStrategy: "concatenate" });
// { tags: ["a", "b"] }
deepMergeWith({ a: { b: 1 } }, [{ a: { c: 2 } }]);
// { a: { b: 1, c: 2 } }
firstDefinedPath(object: object, paths: string[])
Try each dot-notation path in turn, returning the first defined value
found. Values that are null or undefined are skipped, so a path that
exists but holds null does not short-circuit the search. Returns
undefined when no path yields a defined value, or when the input is not a
non-empty object with a non-empty paths array. Unlike firstDefined and
lastDefined, this helper skips both null and undefined.
Parameters
object{object}— The object to inspect.paths{string[]}— The dot-notation paths to try.
Returns
{any} — The first defined path value, or undefined when none exists.
Example
firstDefinedPath({ a: 1, b: 2 }, ["a"]); // 1
firstDefinedPath({ a: 1, b: 2 }, ["c", "a"]); // 1
firstDefinedPath({ a: null, b: 2 }, ["a", "b"]); // 2
firstDefinedPath({ a: { b: { c: "deep" } } }, ["a.b.c"]); // "deep"
firstDefinedPath({ a: 1 }, ["c", "d"]); // undefined
firstDefinedPath([], ["a"]); // undefined
flattenObject(object: object)
Flattens a nested object into a single-level object with dot-notation keys.
Parameters
object{object}— The object to flatten.
Returns
{object} — An object with nested keys expressed as dot-separated paths.
Arrays are preserved as leaf values — they are not flattened into indexed
keys (e.g. "items.0").
Only own enumerable properties are included.
Example
flattenObject({ a: { b: 1, c: 2 }, d: 3 });
// { "a.b": 1, "a.c": 2, "d": 3 }
flattenObject({ items: [1, 2, 3] });
// { "items": [1, 2, 3] }
getPathValue(object: object, path: string, returnValue: any = undefined)
Retrieve the object property value found at path, or returnValue.
Parameters
object{object}— The object to inspect.path{string}— The dot-notation path to retrieve.returnValue{any}— The fallback value when the path cannot be resolved.
Returns
{any} — The path value, or the fallback when the path cannot be found.
Example
getPathValue({ property: "value" }, "property"); // "value"
getPathValue({ property: "value" }, "another"); // undefined
getPathValue({ nested: { property: { value: "seven" } } }, "nested.property.value"); // "seven"
getPathValue({ nested: { property: { value: "seven" } } }, "nested.mistake.value", null); // null
getPathValue([], "property"); // undefined
hasAnyPath(object: object, paths: string[])
Determine if the given object has any of the properties at paths.
Parameters
object{object}— The object to inspect.paths{string[]}— The dot-notation paths to check.
Returns
{boolean} — Whether at least one path exists in the object.
Example
hasAnyPath({ a: { b: { c: 1 } } }, ["a.b.c"]); // true
hasAnyPath({ a: { b: { c: 1 } } }, ["a.b.d", "a.b.c"]); // true
hasAnyPath({ a: { b: { c: 1 } } }, ["a.b.d"]); // false
hasAnyPath({ a: { b: { c: 1 } } }, ["a.b.e", "a.b.f"]); // false
isNonEmptyObject(variable: any)
Determines whether the given variable is both an object (and not null, or
an array), and has at least one property.
Parameters
variable{any}— The value to check.
Returns
{boolean} — Whether the value is an object with at least one own key.
Example
isNonEmptyObject({ property: "value" }); // true
isNonEmptyObject({}); // false
isNonEmptyObject("string"); // false
isObject(variable: any)
Determine whether the given variable is an object, excluding arrays and
null.
Parameters
variable{any}— The value to check.
Returns
{boolean} — Whether the value is a non-null object that is not an array.
Example
isObject({ property: "value" }); // true
isObject(["A", "B", "C", "D"]); // false
isObject(null); // false
isPlainObject(variable: any)
Determine whether the given variable is a plain object literal, excluding
arrays, null, and non-plain objects such as Date, Map, Set, or class
instances.
Parameters
variable{any}— The value to check.
Returns
{boolean} — Whether the value is a plain object.
Example
isPlainObject({ property: "value" }); // true
isPlainObject(["A", "B", "C", "D"]); // false
isPlainObject(new Date()); // false
isPlainObject(null); // false
keyBy(array: object[], key: string)
Convert the given array of objects into a single object, where each object
in the original array is placed under the value of its given key.
Parameters
array{object[]}— The objects to index.key{string}— The property whose value becomes each output key.
Returns
{object | array} — The indexed object, or the original array when the key is invalid.
Objects without the given key are discarded. When several objects share a
key value, the last one is kept. Key values that match built-in property
names, such as __proto__ or toString, are stored as ordinary keys.
Example
keyBy([{ a: 1 }, { a: 2 }], "a"); // { 1: { a: 1 }, 2: { a: 2 } }
keys(object: object)
Returns an array of the keys of the given object.
Parameters
object{object}— The object to read keys from.
Returns
{string[]} — The object keys, or an empty array for an invalid object.
Example
keys({ a: 1, b: 2, c: 3 }); // ["a", "b", "c"]
keys({}); // []
keys("string"); // []
mapArrayProperty(object: object, property: string, mapper: Function)
Returns a shallow copy of object with the array at property replaced by
the result of calling mapper over it. If object[property] is not a
non-empty array, property resolves to [] in the result rather than being
omitted.
Parameters
object{object}— The object to read the array from.property{string}— The property holding the array to map.mapper{Function}— The mapper function, forwarded as-is toArray.prototype.map.
Returns
{object} — A copy with the selected array mapped, or an empty object.
Example
mapArrayProperty({ items: [1, 2, 3] }, "items", (item) => item * 2);
// { items: [2, 4, 6] }
mapArrayProperty({ total: 0 }, "items", (item) => item);
// { total: 0, items: [] }
objectContains(object: object, needle: any, { exclude: string[] = null, include: string[] = null, caseInsensitive: boolean = true, allowPartial: boolean = false })
Returns true if one of the object's values is needle. Also works when
object is an array.
Parameters
object{object}— The object or array to search.needle{any}— The value to find.options{object}— The search options.[options.exclude=null]{string[]}— The object keys to omit from the search.[options.include=null]{string[]}— The only object keys to search.[options.caseInsensitive=true]{boolean}— Whether string comparisons ignore case.[options.allowPartial=false]{boolean}— Whether string comparisons allow partial matches.
Returns
{boolean} — Whether a matching value occurs in the object or array.
String needles are checked case-insensitively by default, and partial
matches can be enabled via option.
Example
objectContains({ name: "Merida" }, "merida"); // true
objectContains({ name: "Moana" }, "merida"); // false
objectContains({ name: "Mulan" }, "mulan", { caseInsensitive: false }); // false
objectContains({ name: { first: "Tiana" } }, "tia"); // false
objectContains({ name: { first: "Tiana" } }, "tia", { allowPartial: true }); // true
objectContains({ names: ["Ariel", "Jasmine"] }, "ariel"); // true
objectContains({ length: 52 }, 5); // false
objectLength(object: object)
Return the number of top-level keys in object. Returns 0 for empty or
non-objects.
Parameters
object{object}— The object to count keys on.
Returns
{number} — The number of own keys, or zero for an invalid object.
Example
objectLength({ a: 1, b: 2 }); // 2
objectLength({}); // 0
objectLength("string"); // 0
omit(object: object, properties: string[])
Returns a new object with the specified properties omitted from the given
object.
Parameters
object{object}— The object to copy from.properties{string[]}— The property keys to omit.
Returns
{object} — A copy without the selected properties.
Example
omit({ a: 1, b: 2, c: 3 }, ["b"]); // { a: 1, c: 3 }
omit({ a: 1, b: 2, c: 3 }, ["a", "c"]); // { b: 2 }
omit({ a: 1, b: 2, c: 3 }, []); // { a: 1, b: 2, c: 3 }
pick(object: object, properties: string[])
Returns an object containing only properties properties from object.
Parameters
object{object}— The object to copy from.properties{string[]}— The property keys to keep.
Returns
{object} — An object containing the selected properties.
Any non-string properties are ignored.
If the object does not have a given property, it is ignored.
Example
pick({ a: "one", b: "two", c: "three" }, ["a", "b"]); // { a: "one", b: "two" }
pick({ a: "one", b: "two", c: "three" }, ["a"]); // { a: "one" }
pick({ a: "one", b: "two", c: "three" }, ["a", "d"]); // { a: "one" }
pickAs(object: object, mapping: object)
Returns a new object with keys from mapping whose values are resolved from
object at the paths given by the mapping values.
Parameters
object{object}— The object to read values from.mapping{object}— The output keys and source paths to use.
Returns
{object} — An object with the selected properties renamed by the mapping.
Uses getPathValue so dot-notation paths are supported.
Missing source paths resolve as undefined — the key is always included in
the result.
Example
pickAs({ id: 1, location: { name: "London" } }, { id: "id", locationName: "location.name" });
// { id: 1, locationName: "London" }
pickAs({ a: 1 }, { a: "a", b: "missing" });
// { a: 1, b: undefined }
pluckPathValues(array: object[], path: string)
Retrieve an array of the path value from each of the objects found in
array.
Parameters
array{object[]}— The objects to read from.path{string}— The dot-notation path to retrieve from each object.
Returns
{any[]} — The value at the path for each valid object.
Any non-objects in array are ignored. Objects that don't have the given
path yield undefined in the result. Empty or invalid input returns [].
Example
pluckPathValues([{ user: { name: "Sophie" } }, { user: { name: "Hannah" } }], "user.name"); // ["Sophie", "Hannah"]
pluckPathValues([{ user: { name: "Sophie" } }, { user: {} }], "user.name"); // ["Sophie", undefined]
pluckPathValues([{ user: { name: "Sophie" } }, "not an object"], "user.name"); // ["Sophie"]
pluckPathValues([], "user.name"); // []
removePathValue(object: object, path: string)
Remove an object property at path. This method makes a copy of the provided
object to not modify the original.
Parameters
object{object}— The object to remove the value from.path{string}— The dot-notation path to remove.
Returns
{object} — A copy of the object without the selected
Related Packages
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 3.0.0 | ^3.5.39 | MIT | |
| 2.0.0 | ^3.5.39 | MIT | |
| 1.7.1 | ^3.5.39 | MIT | |
| 1.7.0 | ^3.5.39 | MIT | |
| 1.6.0 | ^3.5.39 | MIT | |
| 1.5.0 | ^3.5.39 | MIT | |
| 1.4.3 | ^3.5.38 | MIT | |
| 1.4.2 | ^3.5.38 | MIT | |
| 1.4.1 | ^3.5.38 | MIT | |
| 1.4.0 | ^3.5.38 | MIT |