Universal iteration, transformation, and querying operations that work consistently across arrays, objects, and strings. These utilities provide a unified interface for working with different collection types in TypeScript with full type safety.
Converts any value to an array format, useful for normalizing inputs.
/**
* Convert any value to an array
* @param val - Value to convert (if already array, returns as-is; if falsy, returns empty array; otherwise wraps in array)
* @returns Array containing the value
*/
function toArr(val: any): any[];Usage Examples:
import { toArr } from "@formily/shared";
toArr([1, 2, 3]); // [1, 2, 3] (no change)
toArr("hello"); // ["hello"]
toArr(42); // [42]
toArr(null); // []
toArr(undefined); // []Iterate over arrays, objects, or strings with a consistent interface.
/**
* Iterate over collections with unified interface
* @param val - Collection to iterate (array, string, or object)
* @param iterator - Function called for each item
* @param revert - If true, iterate in reverse order
*/
function each(val: string, iterator: EachStringIterator, revert?: boolean): void;
function each<T>(val: T[], iterator: EachArrayIterator<T>, revert?: boolean): void;
function each<T extends {}, TValue extends T[keyof T]>(val: T, iterator: EachObjectIterator<TValue>, revert?: boolean): void;
type EachArrayIterator<T> = (currentValue: T, key: number) => void | boolean;
type EachStringIterator = (currentValue: string, key: number) => void | boolean;
type EachObjectIterator<T = any> = (currentValue: T, key: string) => void | boolean;Usage Examples:
import { each } from "@formily/shared";
// Array iteration
each([1, 2, 3], (value, index) => {
console.log(`${index}: ${value}`);
});
// String iteration
each("hello", (char, index) => {
console.log(`${index}: ${char}`);
});
// Object iteration
each({ a: 1, b: 2 }, (value, key) => {
console.log(`${key}: ${value}`);
});
// Early termination by returning false
each([1, 2, 3, 4, 5], (value, index) => {
if (value > 3) return false; // Stop iteration
console.log(value);
});
// Reverse iteration
each([1, 2, 3], (value, index) => {
console.log(value); // Outputs: 3, 2, 1
}, true);Transform collections while maintaining structure and type safety.
/**
* Transform collections with unified interface
* @param val - Collection to transform
* @param iterator - Transformation function
* @param revert - If true, process in reverse order
* @returns Transformed collection maintaining original structure
*/
function map<T>(val: string, iterator: MapStringIterator<T>, revert?: boolean): T[];
function map<TItem, TResult>(val: TItem[], iterator: MapArrayIterator<TItem, TResult>, revert?: boolean): TResult[];
function map<T extends {}, TResult>(val: T, iterator: MapObjectIterator<T[keyof T], TResult>, revert?: boolean): Record<keyof T, TResult>;
type MapArrayIterator<TItem, TResult> = (currentValue: TItem, key: number) => TResult;
type MapStringIterator<TResult> = (currentValue: string, key: number) => TResult;
type MapObjectIterator<TItem, TResult> = (currentValue: TItem, key: string) => TResult;Usage Examples:
import { map } from "@formily/shared";
// Array mapping
const doubled = map([1, 2, 3], (value) => value * 2);
// Result: [2, 4, 6]
// String mapping
const charCodes = map("abc", (char) => char.charCodeAt(0));
// Result: [97, 98, 99]
// Object mapping
const uppercased = map({ a: "hello", b: "world" }, (value) => value.toUpperCase());
// Result: { a: "HELLO", b: "WORLD" }Reduce collections to a single value with accumulator pattern.
/**
* Reduce collections to single value
* @param val - Collection to reduce
* @param iterator - Reducer function
* @param accumulator - Initial value (optional)
* @param revert - If true, process in reverse order
* @returns Final accumulated value
*/
function reduce<T, U>(val: T[], iterator: MemoArrayIterator<T, U>, accumulator?: U, revert?: boolean): U;
function reduce<T>(val: string, iterator: MemoStringIterator<T>, accumulator?: T, revert?: boolean): T;
function reduce<T extends {}, TValue extends T[keyof T], TResult = any>(val: T, iterator: MemoObjectIterator<TValue, TResult>, accumulator?: TResult, revert?: boolean): TResult;
type MemoArrayIterator<T, U> = (previousValue: U, currentValue: T, key: number) => U;
type MemoStringIterator<T> = (previousValue: T, currentValue: string, key: number) => T;
type MemoObjectIterator<TValue, TResult> = (previousValue: TResult, currentValue: TValue, key: string) => TResult;Usage Examples:
import { reduce } from "@formily/shared";
// Array reduction
const sum = reduce([1, 2, 3, 4], (acc, value) => acc + value, 0);
// Result: 10
// String reduction
const concatenated = reduce("hello", (acc, char) => acc + char.toUpperCase(), "");
// Result: "HELLO"
// Object reduction
const total = reduce({ a: 10, b: 20, c: 30 }, (acc, value) => acc + value, 0);
// Result: 60Test collections with predicate functions.
/**
* Test if all elements pass predicate
* @param val - Collection to test
* @param iterator - Predicate function
* @param revert - If true, test in reverse order
* @returns True if all elements pass predicate
*/
function every<T extends string>(val: T, iterator: EachStringIterator, revert?: boolean): boolean;
function every<T>(val: T[], iterator: EachArrayIterator<T>, revert?: boolean): boolean;
function every<T extends {}>(val: T, iterator: EachObjectIterator, revert?: boolean): boolean;
/**
* Test if any element passes predicate
* @param val - Collection to test
* @param iterator - Predicate function
* @param revert - If true, test in reverse order
* @returns True if any element passes predicate
*/
function some<T extends string>(val: T, iterator: EachStringIterator, revert?: boolean): boolean;
function some<T>(val: T[], iterator: EachArrayIterator<T>, revert?: boolean): boolean;
function some<T extends {}>(val: T, iterator: EachObjectIterator, revert?: boolean): boolean;Usage Examples:
import { every, some } from "@formily/shared";
// Test all elements
const allEven = every([2, 4, 6, 8], (value) => value % 2 === 0);
// Result: true
// Test any element
const hasNegative = some([1, 2, -3, 4], (value) => value < 0);
// Result: true
// Object testing
const allStrings = every({ a: "hello", b: "world" }, (value) => typeof value === "string");
// Result: trueFind elements and their positions in collections.
/**
* Find first element matching predicate
* @param val - Collection to search
* @param iterator - Predicate function
* @param revert - If true, search in reverse order
* @returns First matching element or undefined
*/
function find<T extends string>(val: T, iterator: EachStringIterator, revert?: boolean): any;
function find<T>(val: T[], iterator: EachArrayIterator<T>, revert?: boolean): T;
function find<T extends {}>(val: T, iterator: EachObjectIterator, revert?: boolean): T[keyof T];
/**
* Find index of first element matching predicate
* @param val - Collection to search
* @param iterator - Predicate function
* @param revert - If true, search in reverse order
* @returns Index of first match or -1 if not found
*/
function findIndex<T extends string>(val: T, iterator: EachStringIterator, revert?: boolean): number;
function findIndex<T>(val: T[], iterator: EachArrayIterator<T>, revert?: boolean): number;
function findIndex<T extends {}>(val: T, iterator: EachObjectIterator, revert?: boolean): keyof T;
/**
* Check if collection includes element
* @param val - Collection to search
* @param searchElement - Element to find
* @param revert - If true, search in reverse order
* @returns True if element is found
*/
function includes<T extends string>(val: T, searchElement: string, revert?: boolean): boolean;
function includes<T>(val: T[], searchElement: T, revert?: boolean): boolean;Usage Examples:
import { find, findIndex, includes } from "@formily/shared";
// Find element
const user = find([
{ name: "Alice", age: 25 },
{ name: "Bob", age: 30 }
], (user) => user.age > 28);
// Result: { name: "Bob", age: 30 }
// Find index
const index = findIndex([10, 20, 30], (value) => value > 15);
// Result: 1
// Check inclusion
const hasApple = includes(["apple", "banana", "cherry"], "apple");
// Result: trueSpecialized array operations for reordering elements.
/**
* Move array element from one index to another
* @param array - Array to modify (modified in place)
* @param fromIndex - Source index
* @param toIndex - Destination index
* @returns Modified array (same reference)
*/
function move<T extends any>(array: T[], fromIndex: number, toIndex: number): T[];Usage Examples:
import { move } from "@formily/shared";
const items = ["a", "b", "c", "d", "e"];
move(items, 1, 3); // Move "b" to position 3
// Result: ["a", "c", "d", "b", "e"]
// Invalid indices are ignored
move(items, -1, 10); // No change
move(items, 2, 2); // No change (same position)