@rzl-zone/utils-js
Version:
A modern, lightweight set of JavaScript utility functions with TypeScript support for everyday development, crafted to enhance code readability and maintainability.
1,111 lines (1,084 loc) • 107 kB
TypeScript
/*!
* ====================================================
* Rzl Utils-JS.
* ----------------------------------------------------
* Version: 3.11.0.
* Author: Rizalvin Dwiky.
* Repository: https://github.com/rzl-zone/utils-js.
* ====================================================
*/
import { NumberRangeUnion, Prettify, IsPositive, ParseNumber, Extends, IsStringLiteral, CharAt, AnyString, AnyFunction, IsEmptyString, Trim, IsAny, AnObjectNonArray, IsArray, OrArr, IsNever, TypedArray } from '@rzl-zone/ts-types-plus';
import { a as IsPlainObjectResult, c as IsHasKeysObject } from '../isPlainObject-0p3VveWr.js';
export { A as AcronymsList, G as GetPreciseTypeOptions, I as IsNumberOptions, g as getPreciseType, i as isNumber, b as isPlainObject } from '../isPlainObject-0p3VveWr.js';
/** ----------------------------------------------------------
* * ***Predicate: `areArraysEqual`.***
* ----------------------------------------------------------
* **Compares two arrays deeply to check if they are equal.**
* @description Supports deep comparison of arrays containing nested arrays or objects,
* can also ignore the order of elements at all levels by recursively sorting.
* @param {unknown[]} array1
* ***The first array to compare, can contain nested arrays or objects.***
* @param {unknown[]} array2
* ***The second array to compare against, should match structure of `array1`.***
* @param {boolean|undefined} [ignoreOrder=false]
* ***Whether to ignore the order of elements when comparing.***
* - If `true`, will sort both arrays recursively before comparing, default is `false`.
* @returns {boolean}
* Returns `true` if both arrays are deeply equal, otherwise `false`.
* @throws **{@link TypeError | `TypeError`}** if `array1` or `array2` are not arrays, or if `ignoreOrder` is not a boolean.
* @example
* ```ts
* areArraysEqual([1, 2, 3], [1, 2, 3]);
* // ➔ true
* areArraysEqual([1, 2, 3], [3, 2, 1]);
* // ➔ false
* areArraysEqual([1, 2, 3], [3, 2, 1], true);
* // ➔ true (order ignored)
* areArraysEqual([{ x: 1 }, { y: 2 }], [{ y: 2 }, { x: 1 }], true);
* // ➔ true
* ```
*/
declare const areArraysEqual: (array1: unknown[], array2: unknown[], ignoreOrder?: boolean) => boolean;
/** ---------------------------------
* * ***Predicate: `areObjectsEqual`.***
* ---------------------------------
* **Compares two objects for deep equality.**
* @template T1 The type of the first object.
* @template T2 The type of the second object.
* @param {*} object1 - The first object to compare.
* @param {*} object2 - The second object to compare.
* @returns {boolean} Return `true` if both objects are deeply equal, otherwise `false`.
* @example
* areObjectsEqual({ a: 1, b: 2 }, { a: 1, b: 2 });
* // ➔ true
* areObjectsEqual({ a: 1 }, { a: 1, b: undefined });
* // ➔ false
* areObjectsEqual([1, 2, 3], [1, 2, 3]);
* // ➔ true
*/
declare const areObjectsEqual: (object1: unknown, object2: unknown) => boolean;
/** ---------------------------------
* * ***Predicate: `areURLsEqualPath`.***
* ---------------------------------
* **Checks if two URLs are the same, ignoring query parameters, this function compares only the protocol, host, and pathname.**
* @param {URL} urlA - The first URL to compare.
* @param {URL} urlB - The second URL to compare.
* @returns {boolean} Returns `true` if both URLs are the same (ignoring search parameters), otherwise `false`.
* @example
* // Same domain, same path, different query -> true
* areURLsEqualPath(
* new URL("https://example.com/page?a=1"),
* new URL("https://example.com/page?b=2")
* );
* // ➔ true
*
* // Same domain, different path -> false
* areURLsEqualPath(
* new URL("https://example.com/page1"),
* new URL("https://example.com/page2")
* );
* // ➔ false
*
* // Different protocol -> false
* areURLsEqualPath(
* new URL("http://example.com/page"),
* new URL("https://example.com/page")
* );
* // ➔ false
*
* // Same protocol, same host, same path (ignores query & hash) -> true
* areURLsEqualPath(
* new URL("https://example.com/page#section"),
* new URL("https://example.com/page")
* );
* // ➔ true
*/
declare const areURLsEqualPath: (urlA: URL, urlB: URL) => boolean;
/** ---------------------------------
* * ***Predicate: `areURLsIdentical`.***
* ---------------------------------
* **Checks if two URLs are exactly the same, including protocol, host, pathname, and query parameters.**
* @param {URL} urlA - The first URL to compare.
* @param {URL} urlB - The second URL to compare.
* @returns {boolean} Returns `true` if both URLs are identical, otherwise `false`.
* @example
* // Identical URLs -> true
* areURLsIdentical(
* new URL("https://example.com/page?a=1"),
* new URL("https://example.com/page?a=1")
* );
* // ➔ true
*
* // Same path, different query parameter -> false
* areURLsIdentical(
* new URL("https://example.com/page?a=1"),
* new URL("https://example.com/page?b=2")
* );
* // ➔ false
*
* // Same host & query, but different protocol -> false
* areURLsIdentical(
* new URL("http://example.com/page?a=1"),
* new URL("https://example.com/page?a=1")
* );
* // ➔ false
*
* // Same everything except trailing slash -> false
* areURLsIdentical(
* new URL("https://example.com/page"),
* new URL("https://example.com/page/")
* );
* // ➔ false
*/
declare const areURLsIdentical: (urlA: URL, urlB: URL) => boolean;
type OptionsTextContainsAll = {
/** If `true`, matches whole words only, defaultValue is `false`.
*
* @default false
*/
exactMatch?: boolean;
/** Optional regex flags (default: `"i"` for case-insensitive).
*
* @default "i"
*/
flags?: string;
};
/** ----------------------------------------------------------
* * ***Predicate: `textContainsAll`.***
* ----------------------------------------------------------
* **Checks if the given `text` contains all of the specified `searchWords`.**
* - **Behavior:**
* - Returns `false` if `text` or `searchWords` is `null`/`undefined`/invalid.
* - Uses **regular expressions** for flexible pattern matching.
* - **Escapes special characters** to prevent regex injection attacks.
* - **Trims input** to avoid false positives with empty spaces.
* - **Supports exact word matching** (optional).
* @param {string|null|undefined} text - The string text to search within.
* @param {string[]|null} [searchWords] - An array of words/phrases to match against the text.
* @param {OptionsTextContainsAll} [options] - Optional configuration object.
* @param {OptionsTextContainsAll["exactMatch"]} [options.exactMatch=false] - If `true`, matches whole words only, defaultValue is `false`.
* @param {OptionsTextContainsAll["flags"]} [options.flags="i"] - Optional regex flags (default: `"i"` for case-insensitive).
* @returns {boolean} Return `true` if all `searchWords` are found in `text`, otherwise `false`.
* @example
* textContainsAll("Hello world, WithAI APP", ["Hello", "world"]);
* // ➔ true
* textContainsAll("JavaScript and TypeScript", ["Java", "Script"]);
* // ➔ true
* textContainsAll("Machine Learning", ["AI", "Learning"]);
* // ➔ false
* textContainsAll("open-source", ["open"], { exactMatch: true });
* // ➔ false (because options `exactMatch=true`)
* textContainsAll(null, ["test"]);
* // ➔ false (invalid text)
* textContainsAll("Hello", null);
* // ➔ false (invalid searchWords)
*/
declare const textContainsAll: <T extends string>(text?: T | null, searchWords?: T[] | string[] | null, options?: OptionsTextContainsAll) => boolean;
type OptionsTextContainsAny = {
/** If `true`, matches whole words only, defaultValue is `false`.
*
* @default false
*/
exactMatch?: boolean;
/** Optional regex flags (default: `"i"` for case-insensitive).
*
* @default "i"
*/
flags?: string;
};
/** ----------------------------------------------------------
* * ***Predicate: `textContainsAny`.***
* ----------------------------------------------------------
* **Checks if the given `text` contains at least one of the specified `searchWords`.**
* - **Behavior:**
* - Returns `false` if `text` or `searchWords` is `null`/`undefined`/invalid.
* - Uses **regular expressions** for flexible pattern matching.
* - **Escapes special characters** to prevent regex injection attacks.
* - **Trims input** to avoid false positives with empty spaces.
* - **Supports exact word matching** (optional).
* @param {string|null|undefined} text - The string text to search within.
* @param {string[]|null} [searchWords] - An array of words/phrases to match against the text.
* @param {OptionsTextContainsAny} [options] - Optional configuration object.
* @param {OptionsTextContainsAny["exactMatch"]} [options.exactMatch=false] - If `true`, matches whole words only, defaultValue is `false`.
* @param {OptionsTextContainsAny["flags"]} [options.flags="i"] - Optional regex flags (default: `"i"` for case-insensitive).
* @returns {boolean} Return `true` if at least one `searchWord` is found in `text`, otherwise `false`.
* @example
* textContainsAny("Hello world", ["hello", "test"]);
* // ➔ true
* textContainsAny("withAI APP", ["chat", "ai"]);
* // ➔ false
* textContainsAny("TypeScript is great!", ["script", "java"]);
* // ➔ true
* textContainsAny("open-source", ["open"], { exactMatch: true });
* // ➔ false (because options `exactMatch=true`)
* textContainsAny(null, ["test"]);
* // ➔ false (invalid text)
* textContainsAny("Hello", null);
* // ➔ false (invalid searchWords)
*/
declare const textContainsAny: <T extends string>(text?: T | null, searchWords?: T[] | string[] | null, options?: OptionsTextContainsAny) => boolean;
/** ----------------------------------------------------------
* * ***Predicate: `doesKeyExist`.***
* ----------------------------------------------------------
* **Recursively checks if a given key exists in an object or array.**
* - **Behavior:**
* - **Supports deeply nested objects and arrays**, searching recursively.
* - Uses `Object.prototype.hasOwnProperty.call()` to safely check if the
* key exists at each level, even if its value is `null` or `undefined`.
* - Optimized to return `true` immediately when the key is found (short-circuits).
* - Handles edge cases gracefully:
* - Returns `false` for `null`, `undefined`, or non-object inputs.
* - Returns `false` if key is not found anywhere, even in deeply nested
* structures.
* - **ℹ️ Note:**
* - This function only checks for **the existence of the key itself**,
* not whether its value is non-null or non-undefined.
* - If you need to check for both existence and meaningful value, write a stricter function.
* @template T - The type of the input object or array.
* @param {T | Record<string, unknown> | unknown[]} object - The object or array to search.
* @param {PropertyKey} key - The key to look for (string, number, or symbol).
* @returns {boolean} Returns `true` if the key exists anywhere in the object or array (even with `null` / `undefined` value), otherwise `false`.
* @example
* doesKeyExist({ name: "John", age: 30 }, "age");
* // ➔ true
* doesKeyExist({ user: { profile: { email: "test@example.com" } } }, "email");
* // ➔ true
* doesKeyExist([{ id: 1 }, { id: 2 }], "id");
* // ➔ true
* doesKeyExist({ a: { b: { c: 10 } } }, "d");
* // ➔ false
* doesKeyExist(null, "name");
* // ➔ false
* doesKeyExist(undefined, "test");
* // ➔ false
*
* // Key exists even if value is null or undefined:
* doesKeyExist({ a: null, b: undefined, c: { d: null } }, "a"); // ➔ true
* doesKeyExist({ a: null, b: undefined, c: { d: null } }, "b"); // ➔ true
* doesKeyExist({ a: null, b: undefined, c: { d: null } }, "d"); // ➔ true
*
* doesKeyExist({ a: 1 }, true);
* // ➔ ❌ Throws TypeError
* doesKeyExist({ a: 1 }, ["not", "valid"]);
* // ➔ ❌ Throws TypeError
*/
declare const doesKeyExist: (object: Record<string, unknown> | unknown[], key: PropertyKey) => boolean;
/** ----------------------------------------------------------
* * ***Predicate: `arrayHasAnyMatch`.***
* ----------------------------------------------------------
* **Checks if at least one element from `targetArray` exists in `sourceArray`.**
* - **Behavior:**
* - Uses `Set` for **faster lookup** compared to `Array.prototype.includes()`.
* - Supports **any data type** (`number`, `string`, `boolean`, `object`, `array`, `function`, etc.).
* - Uses **reference equality** for non-primitive values (object, array, function).
* - Returns `false` if either array is missing, empty, or not an array.
* @template T - The expected type of array elements.
* @param {T[] | null | undefined} sourceArray - The array to search within.
* @param {T[] | null | undefined} targetArray - The array containing elements to match.
* @returns {boolean}
* ***Return:***
* - `true` if **at least one element from `targetArray` is strictly found
* in `sourceArray`**.
* - Comparison uses:
* - **Value equality** for primitives (`number`, `string`, `boolean`, `null`, `undefined`).
* - **Reference equality** for `objects`, `arrays`, and `functions`.
* - `false` if:
* - No matching elements exist,
* - Either array is not provided, not an actual array, or is empty.
* @example
* arrayHasAnyMatch(["apple", "banana", "cherry"], ["banana", "grape"]);
* // ➔ true
* arrayHasAnyMatch(["red", "blue"], ["green", "yellow"]);
* // ➔ false
* arrayHasAnyMatch([1, 2, 3], [3, 4, 5]);
* // ➔ true
* arrayHasAnyMatch([], ["test"]);
* // ➔ false
* arrayHasAnyMatch(["A", "B", "C"], []);
* // ➔ false
*
* const obj = { x: 1 };
* arrayHasAnyMatch([obj], [obj]);
* // ➔ true (same reference)
* arrayHasAnyMatch([{ x: 1 }], [{ x: 1 }]);
* // ➔ false (different reference)
*
* const fn = () => "hello";
* arrayHasAnyMatch([fn], [fn]);
* // ➔ true
* arrayHasAnyMatch([() => "hello"], [() => "hello"]);
* // ➔ false (different function reference)
*
* const arr = [1, 2];
* arrayHasAnyMatch([arr], [arr]);
* // ➔ true
* arrayHasAnyMatch([[1, 2]], [[1, 2]]);
* // ➔ false (different array object)
*/
declare const arrayHasAnyMatch: <T>(sourceArray: T[] | null | undefined, targetArray: T[] | null | undefined) => boolean;
/** Restrict array indices to a fixed numeric range (1–25). */
type ArrayIndex = NumberRangeUnion<1, 25>;
/** Remove `undefined` from a type. */
type NonUndef<T> = T extends undefined ? never : T;
/** Remove `null` from a type. */
type NonNull<T> = T extends null ? never : T;
/** Convert optional boolean for "discard undefined" to actual boolean. */
type EffectiveDiscardUndefined<O extends boolean | undefined> = O extends boolean ? O : true;
/** Convert optional boolean for "discard null" to actual boolean. */
type EffectiveDiscardNull<O extends boolean | undefined> = O extends boolean ? O : false;
/** Unwrap array type. */
type UnwrapArray<T> = T extends (infer U)[] ? U : T extends readonly (infer U)[] ? U : T;
/** Force symbol key to be deep required. */
type IsOptionalKey<T, K extends keyof T> = Record<never, never> extends Pick<T, K> ? true : false;
/** * ***Returns numeric keys of an object.***
*
* @private ***types for {@link hasOwnProp}.***
*/
type NumericKeyOfHasOwnProp<Obj> = Extract<keyof Obj, number>;
/** * ***Generate all nested keys of an object or array in dot/bracket notation.***
*
* @private ***types for {@link hasOwnProp}.***
*
* Example:
* ```ts
* type Keys = NestedKeyOfHasOwnProp<{ users: { name: string }[] }>
* // Keys = "users" | "users.[number]" | "users.[number].name"
* ```
*/
type NestedKeyOfHasOwnProp<T> = T extends readonly (infer U)[] ? `[${number}]` | `[${number}].${NestedKeyOfHasOwnProp<U>}` : T extends object ? {
[K in keyof T & (string | number)]: K extends string | number ? NonNullable<T[K]> extends readonly unknown[] ? `${K}` | `${K}.[${ArrayIndex}]` | `${K}.[${ArrayIndex}].${NestedKeyOfHasOwnProp<UnwrapArray<T[K]>>}` : NonNullable<T[K]> extends object ? `${K}` | `${K}.${NestedKeyOfHasOwnProp<NonNullable<T[K]>>}` : `${K}` : never;
}[keyof T & (string | number)] : never;
/** Apply discard rules to the last key of a path.
*
* Rules:
* - If discardUndefined=true -> remove `undefined` from value
* - If discardNull=true -> remove `null` from value
*
* Order: first strip undefined (if requested), then strip null (if requested)
*/
type ApplyLastRulesHasOwnProp<V, DiscardU extends boolean, DiscardN extends boolean> = DiscardU extends true ? DiscardN extends true ? NonNull<NonUndef<V>> : NonUndef<V> : DiscardN extends true ? NonNull<V> : V | Extract<V, undefined>;
/** Force an array index N to type U. */
type RefineArrayAtIndex<T extends readonly unknown[], N extends number, U> = T & {
[K in N]: U;
};
/** Narrow object/array type based on a path string.
*
* @template T - object type to narrow
* @template P - path string like "user.addresses.[2].zip"
* @template DU - discard undefined
* @template DN - discard null
*/
type NarrowByPathHasOwnProp<T, P extends string, DU extends boolean = true, DN extends boolean = false> = P extends `${infer Head}.${infer Rest}` ? Head extends `[${infer N extends number}]` ? T extends readonly (infer U)[] ? RefineArrayAtIndex<T, N, NarrowByPathHasOwnProp<U, Rest, DU, DN>> : T : Head extends keyof T ? Rest extends `[${infer M extends number}]${infer R}` ? M extends R ? {
[K in keyof T]-?: NarrowByPathHasOwnProp<EffectiveDiscardUndefined<DU> extends true ? NonUndef<T[K]> : EffectiveDiscardNull<DN> extends true ? NonNull<T[K]> : T[K], Rest, DU, DN>;
} : EffectiveDiscardUndefined<DU> extends true ? {
[K in keyof T]-?: K extends Head ? Exclude<NarrowByPathHasOwnProp<EffectiveDiscardNull<DN> extends true ? Exclude<T[K], null> : EffectiveDiscardUndefined<DU> extends true ? Exclude<T[K], undefined> : T[K], Rest, DU, DN>, undefined> : EffectiveDiscardNull<DN> extends true ? Exclude<T[K], null> : EffectiveDiscardUndefined<DU> extends true ? Exclude<T[K], undefined> : T[K];
} : {
[K in keyof T]: K extends Head ? NarrowByPathHasOwnProp<EffectiveDiscardNull<DN> extends true ? Exclude<T[K], null> : EffectiveDiscardUndefined<DU> extends true ? Exclude<T[K], undefined> : T[K], Rest, DU, DN> : EffectiveDiscardNull<DN> extends true ? Exclude<T[K], null> : EffectiveDiscardUndefined<DU> extends true ? Exclude<T[K], undefined> : T[K];
} : {
[K in keyof T]: K extends Head ? NarrowByPathHasOwnProp<NonNullable<T[K]>, Rest, DU, DN> : T[K];
} & {
[K in Head]-?: NarrowByPathHasOwnProp<NonNullable<T[K]>, Rest, DU, DN>;
} : T : P extends `[${infer N extends number}]` ? T extends readonly (infer U)[] ? RefineArrayAtIndex<T, N, ApplyLastRulesHasOwnProp<NonNullable<U>, DU, DN>> : T : P extends keyof T ? DU extends true ? {
[K in keyof T]: K extends P ? ApplyLastRulesHasOwnProp<T[K], DU, DN> : T[K];
} & {
[K in P]-?: ApplyLastRulesHasOwnProp<T[P], DU, DN>;
} : {
[K in keyof T]: K extends P ? ApplyLastRulesHasOwnProp<T[K], DU, DN> : T[K];
} : T;
/** * ***Expand an array/string/function into a nested type according
* to a dot/bracket path.***
* @private ***types for {@link hasOwnProp}.***
*/
type SmartDetectStringHasOwnProp<Obj extends string | undefined | null, Key extends string | number> = Obj extends undefined ? undefined : Obj extends null ? null : IsPositive<ParseNumber<Key>> extends true ? Extends<IsStringLiteral<Obj>, true> extends true ? CharAt<Exclude<Obj, null | undefined>, ParseNumber<Key>> : string | undefined | null : IsPositive<ParseNumber<Key>> extends true ? string | undefined | null : AnyString | undefined | null;
/** @private ***types for {@link hasOwnProp}.*** */
type SmartDetectArrayFuncHasOwnProp<Obj extends unknown[] | AnyFunction, Key extends PropertyKey> = Prettify<Obj & DotToNestedSpecialSmartDetect<Key> & {
length: number;
}, {
recursive: false;
}>;
/** * ***Smartly detect nested path keys of an unknown object or function,
* falls-back to inferred nested structure when path is not valid.***
*
* @private ***types for {@link hasOwnProp}.***
*/
type SmartDetectUnknownKeyHasOwnProp<Obj extends unknown | AnyFunction, Key extends PropertyKey, DiscardUndefined extends boolean = true, DiscardNull extends boolean = false> = Trim<Key> extends "" ? Obj : Prettify<Obj & (Key extends NestedKeyOfHasOwnProp<Obj> ? GuardedHasOwnProp<Obj, Key, DiscardUndefined, DiscardNull> : DotToNestedSpecialSmartDetect<Key>), {
recursive: true;
}>;
/** Convert dot/bracket path string to nested object type with leaf value.
* Path not found in object key ➔ return unknown.
*/
type DotToNestedSpecialSmartDetect<Path extends PropertyKey, Value = unknown> = IsEmptyString<Extract<Path, string>> extends true ? undefined : Path extends `${infer Head}.${infer Rest}` ? Head extends `[${number}]` ? DotToNestedSpecialSmartDetect<Rest, Value>[] : {
[Key in Head]: DotToNestedSpecialSmartDetect<Rest, Value>;
} : Path extends `[${number}]` ? Value[] : {
[Key in Path]: Value;
};
/** * ***Guarded wrapper for `NarrowByPathHasOwnProp` with `Prettify`.***
* @private ***types for {@link hasOwnProp}.***
*/
type GuardedHasOwnProp<Obj, Key extends NestedKeyOfHasOwnProp<Obj>, DiscardUndefined extends boolean | undefined, DiscardNull extends boolean | undefined> = Prettify<Obj & NarrowByPathHasOwnProp<Obj, Key & string, EffectiveDiscardUndefined<DiscardUndefined>, EffectiveDiscardNull<DiscardNull>>, {
recursive: true;
}>;
/** * ***Make a specific symbol key deeply required in an object symbols.***
* **Used internally to enforce stronger type narrowing.**
* @private ***types for {@link hasOwnProp}.***
*/
type DeepRequiredSymbolHasOwnProp<Obj, Sym extends symbol, DU extends boolean = true, DN extends boolean = false> = Prettify<Obj & ({
[K in keyof Obj & Sym as DU extends true ? K : never]-?: DN extends true ? NonNull<NonUndef<Obj[K]>> : NonUndef<Obj[K]>;
} & {
[K in keyof Obj & Sym as DU extends true ? never : K]?: DN extends true ? NonNull<Obj[K]> : Obj[K];
}), {
recursive: true;
}>;
/** * ***Apply discard rules to numeric keys in an object type.***
*
* - If `discardUndefined = true` ➔ undefined removed, key required
* - If `discardNull = true` ➔ null removed
*
* @private ***types for {@link hasOwnProp}.***
*/
type NumericKeyHasOwnPropMapped<Obj extends object, K extends NumericKeyOfHasOwnProp<Obj>, DU extends boolean, DN extends boolean> = Prettify<Obj & (IsOptionalKey<Obj, K> extends true ? {
[P in K]?: DN extends true ? NonNull<Obj[K]> : Obj[K];
} & (DU extends true ? {
[P in K]-?: NonUndef<Obj[K]>;
} : Record<never, never>) : {
[P in K]-?: DN extends true ? NonNull<Obj[K]> : Obj[K];
} & (DU extends true ? {
[P in K]-?: NonUndef<Obj[K]>;
} : Record<never, never>)), {
recursive: true;
}>;
/** * ***Options to control `hasOwnProp` behavior.***
* @private ***types options for {@link hasOwnProp}.***
*/
type HasOwnPropOptions<DiscardUndefined extends boolean = true, DiscardNull extends boolean = false> = {
/** If `true` ***(default)***, properties with `undefined` values are treated as non-existent.
*
* - **Effects:**
* - **Runtime:** `hasOwnProp(obj, key)` returns `false` if the property exists but its value is `undefined`.
* - **TypeScript narrowing:** The property's type is narrowed to exclude `undefined`.
* - **Example:**
* ```ts
* const obj = { a: undefined, b: 123 };
* hasOwnProp(obj, "a"); // ➔ false
* hasOwnProp(obj, "a", { discardUndefined: false }); // ➔ true
* ```
*/
discardUndefined?: DiscardUndefined;
/** If `true` ***(default: `false`)***, properties with `null` values are treated as non-existent.
*
* - **Effects:**
* - **Runtime:** `hasOwnProp(obj, key)` returns `false` if the property exists but its value is `null`.
* - **TypeScript narrowing:** The property's type is narrowed to exclude `null`.
* - **Example:**
* ```ts
* const obj = { a: null, b: 123 };
* hasOwnProp(obj, "a"); // ➔ true (default discardNull = false)
* hasOwnProp(obj, "a", { discardNull: true }); // ➔ false
* ```
*/
discardNull?: DiscardNull;
};
/** -------------------------------------------------------
* * ***Predicate: `hasOwnProp`.***
* -------------------------------------------------------
* **A **type-safe** replacement for `Object.prototype.hasOwnProperty` with runtime validation and **TypeScript-aware type narrowing**.**
* - #### Supported Targets:
* - **Plain objects** ➔ `{ foo: "bar" }`.
* - **Arrays** ➔ `[ { id: 1 }, { id: 2 } ]`.
* - **Strings** ➔ `"hello"` (as array-like objects with `.length`, index, etc.).
* - **Functions** ➔ callable objects with extra props.
* - **Symbols** ➔ own property symbols.
* - #### Key Advantages over `in` or `obj.hasOwnProperty(key)`:
* - Supports **dot/bracket path notation** (e.g. `"user.address.city"`, `"addresses[0].zip"`).
* - Handles **symbol** keys safely.
* - **Narrows** the type of `obj` in TypeScript (stronger type safety).
* - Configurable handling of **`undefined`** and **`null`**.
* - #### Runtime Behavior:
* - ***✅ Returns `true` if:***
* - Value `obj` is an object/array/string/function **and** the property
* exists **and**, it passes the `options` checks.
* - ***❌ Returns `false` if:***
* - Value `obj` is not a valid type.
* - The property does not exist.
* - The value is `undefined` and `discardUndefined: true` (**default**).
* - The value is `null` and `discardNull: true`.
* - The `key` (after trimming) is an **empty string** ➔ treated as **invalid**.
* - #### TypeScript Behavior:
* - ***Inside an `if (hasOwnProp(...)) {}` block:***
* - The property is **guaranteed to exist**.
* - Depending on `options`, the property type is narrowed to exclude
* `undefined` and/or `null`.
* - #### ⚠️ Caveats:
* - ***Empty keys are invalid:***
* - If the `key` string is empty (`""`) after trimming whitespace or other characters,
* it will **not** be considered a valid property and always returns `false`.
* - ***Arrays are limited by TypeScript inference:***
* - Checking index `[0]` only narrows **that specific index**, not the rest, example:
* 1. `hasOwnProp(users, "[0].id")` does **not** imply `users[1].id` exists.
* - 👉 For different indices, use **optional chaining** (`users[1]?.id`).
* - ***Autocomplete limitation for array indices:***
* - Autocompletion for `[index]` is only supported up to **25** (`[0]` ➔ `[24]`).
* - This limit is intentional for **performance and safety:**
* 1. Generating infinite union types for all possible indices would cause
* **TypeScript IntelliSense to hang or crash**.
* - ℹ️ You can still check higher indices manually (e.g. `"[999].id"`),
* but they will not show up in IntelliSense suggestions.
* @param {HasOwnPropOptions} [options] - ***Optional configuration object.***
* @param {HasOwnPropOptions["discardUndefined"]} [options.discardUndefined=true]
* ***If `true`, properties with `undefined` values are treated as **missing**, default: `true`.***
* @param {HasOwnPropOptions["discardNull"]} [options.discardNull=false]
* ***If `true`, properties with `null` values are treated as **missing**, default: `false`.***
* @param {*} obj ***The `object`, `array`, `string`, `function`, or `other value` to check against.***
* @param {PropertyKey} key
* ***The property key to check, can be:***
* - `string` (supports dot/bracket paths, e.g. `"user.address.city"`, `"[0].id"`).
* - `number` (array-like index).
* - `symbol` (own property symbols).
* @returns {boolean} Return `true` if the property exists (and passes `options`), otherwise `false`.
* @example
*
* - #### ✅ Objects:
* ```ts
* const obj: { name?: string | null } = {};
*
* if (hasOwnProp(obj, "name")) {
* // obj is now ➔ { name: string | null }
* console.log(obj.name); // string | null
* }
*
* if (hasOwnProp(obj, "name", { discardUndefined: true, discardNull: true })) {
* // obj is now ➔ { name: string }
* console.log(obj.name.toUpperCase()); // safe
* }
* ```
* - #### ✅ Arrays:
* ```ts
* const users = [{ id: 1 }, { id: 2 }];
*
* if (hasOwnProp(users, "[1].id")) {
* // ➔ users[1].id is guaranteed to exist
* console.log(users[1].id); // number
* }
*
* // ⚠️ Caveat: narrowing only applies to checked index
* if (hasOwnProp(users, "[0].id")) {
* console.log(users[0].id); // ✅ safe
* console.log(users[1].id); // ❌ not guaranteed!
* }
*
* // 👉 Solution: optional chaining
* console.log(users[1]?.id); // ➔ safe, even without narrowing
* ```
*
* - #### ✅ Symbols:
* ```ts
* const secret = Symbol("secret");
* const obj2 = { [secret]: 42 };
*
* if (hasOwnProp(obj2, secret)) {
* console.log(obj2[secret] + 1); // ➔ 43
* }
* ```
* - #### ✅ Strings:
* ```ts
* if (hasOwnProp("hello", "length")) {
* console.log("hello".length); // ➔ 5
* }
*
* if (hasOwnProp("hello", 1)) {
* console.log("hello"[1]); // ➔ "e"
* }
* ```
* - #### ✅ Functions:
* ```ts
* function fn() {}
* fn.extra = 123;
*
* if (hasOwnProp(fn, "extra")) {
* console.log(fn.extra); // ➔ 123
* }
* ```
* - #### ❌ Empty key:
* ```ts
* const obj = { a: 1 };
*
* hasOwnProp(obj, ""); // ➔ false (invalid key)
* hasOwnProp(obj, " "); // ➔ false (trimmed to empty)
* ```
*/
declare function hasOwnProp<Obj>(obj: IsAny<Obj> extends true ? Obj : never, key: PropertyKey, options?: HasOwnPropOptions<boolean, boolean>
/** @ts-expect-error we force `any` to `unknown` at result */
): obj is unknown;
declare function hasOwnProp<Obj extends null | undefined>(obj: Obj, key: PropertyKey, options?: HasOwnPropOptions<boolean, boolean>): false;
declare function hasOwnProp<Obj extends object | AnyFunction, Key extends NestedKeyOfHasOwnProp<Obj>, DiscardUndefined extends boolean = true, DiscardNull extends boolean = false>(obj: Obj | null | undefined, key: Key, options?: HasOwnPropOptions<DiscardUndefined, DiscardNull>
/** @ts-expect-error we force to override recursive type result */
): obj is GuardedHasOwnProp<Obj, Key, DiscardUndefined, DiscardNull>;
declare function hasOwnProp<Obj extends object, Num extends NumericKeyOfHasOwnProp<Obj>, DiscardUndefined extends boolean = true, DiscardNull extends boolean = false>(obj: Obj | null | undefined, key: Num, options?: HasOwnPropOptions<DiscardUndefined, DiscardNull>
/** @ts-expect-error we force to override recursive type result */
): obj is NumericKeyHasOwnPropMapped<Obj, Num, DiscardUndefined, DiscardNull>;
declare function hasOwnProp<Obj extends object | AnyFunction, Sym extends symbol, DiscardUndefined extends boolean = true, DiscardNull extends boolean = false>(obj: Obj | null | undefined, key: Sym, options?: HasOwnPropOptions<DiscardUndefined, DiscardNull>
/** @ts-expect-error we force to override recursive type result */
): obj is DeepRequiredSymbolHasOwnProp<Obj, Sym, DiscardUndefined, DiscardNull>;
declare function hasOwnProp<Obj extends string | null | undefined, Key extends string | number>(obj: Obj | null | undefined, key: Key, options?: HasOwnPropOptions<boolean, boolean>
/** @ts-expect-error we force to override recursive type result */
): obj is IsStringLiteral<SmartDetectStringHasOwnProp<Obj, Key>> extends true ? AnyString | SmartDetectStringHasOwnProp<Obj, Key> : SmartDetectStringHasOwnProp<Obj, Key>;
declare function hasOwnProp<Obj extends unknown[] | AnyFunction, Key extends PropertyKey>(obj: Obj, key: Key, options?: HasOwnPropOptions<boolean, boolean>): obj is SmartDetectArrayFuncHasOwnProp<Obj, Key>;
declare function hasOwnProp<Obj extends unknown | AnyFunction, Key extends PropertyKey, DiscardUndefined extends boolean = true, DiscardNull extends boolean = false>(obj: Obj, key: Key | "length" | (IsPlainObjectResult<Obj> extends never ? never : keyof Obj), options?: HasOwnPropOptions<DiscardUndefined, DiscardNull>
/** @ts-expect-error we force to override recursive type result */
): obj is SmartDetectUnknownKeyHasOwnProp<Obj, Key, DiscardUndefined, DiscardNull>;
/** -------------------
* * ***Type guard: `isArguments`.***
* -------------------
* **Checks if `value` is likely an `arguments` object.**
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an ***[`IArguments`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments)*** object, else `false`.
* @example
* isArguments(function() { return arguments; }());
* // ➔ true
* isArguments([1, 2, 3]);
* // ➔ false
*/
declare const isArguments: (value: unknown) => value is IArguments;
/** ----------------------------------------------------------
* * ***Type guard: `isArray`.***
* ----------------------------------------------------------
***Checks if a value is an ***[`Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)***.**
* - **Behavior:**
* - Uses ***[`Array.isArray`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray)*** for reliable and safe type checking.
* - Supports TypeScript **type narrowing** using `value is T[]`.
* - Handles edge cases like `null`, `undefined`, and non-array objects.
* @template T - The expected type of array elements.
* @param {*} value - The value to check.
* @returns {boolean} Returns `true` if the value is an `array`, otherwise `false`.
* @example
* isArray([1, 2, 3]);
* // ➔ true
* isArray([]);
* // ➔ true
* isArray("hello");
* // ➔ false
* isArray({ key: "value" });
* // ➔ false
* isArray(null);
* // ➔ false
* isArray(undefined);
* // ➔ false
*/
declare function isArray<T extends unknown[]>(value: T): value is Extract<T, unknown[]>;
declare function isArray<T extends readonly unknown[]>(value: T): value is Extract<T, readonly unknown[]>;
declare function isArray(value: unknown): value is unknown[];
/** ----------------------------------------------------
* * ***Type guard: `isArrayBuffer`.***
* ----------------------------------------------------
* **Checks if `value` is classified as an `ArrayBuffer` object.**
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is instance of ***[`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer)***, else `false`.
* @example
* isArrayBuffer(new ArrayBuffer(2));
* // ➔ true
* isArrayBuffer(new Array(2));
* // ➔ false
*/
declare function isArrayBuffer(value: unknown): value is ArrayBuffer;
/** ----------------------------------------------------
* * ***Type guard: `isArrayLike`.***
* ----------------------------------------------------
* **Checks if `value` is array-like, a value is considered array-like if it's
* not a function and has a `value.length` that's an integer greater than or
* equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.**
* @template T - The type of the value being checked.
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is array-like, else `false`.
* @example
* isArrayLike([1, 2, 3]);
* // ➔ true
* isArrayLike(document.body.children);
* // ➔ true
* isArrayLike(noop);
* // ➔ false
* isArrayLike('abc');
* // ➔ false
*/
declare function isArrayLike<T extends {
__anyHack: unknown;
}>(value: T): boolean;
declare function isArrayLike(value: AnyFunction | null | undefined): value is never;
declare function isArrayLike(value: unknown): value is {
length: number;
};
/** ----------------------------------------------------
* * ***Type guard: `isArrayLikeObject`.***
* ----------------------------------------------------
* **This method is like ***`isArrayLike` utility function*** except that
* it also checks if `value` is an object.**
* @template T - The type of the value being checked.
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is `array-like object`, else `false`.
* @example
* isArrayLikeObject([1, 2, 3]);
* // ➔ true
* isArrayLikeObject(document.body.children);
* // ➔ true
* isArrayLikeObject('abc');
* // ➔ false
* isArrayLikeObject(noop);
* // ➔ false
*/
declare function isArrayLikeObject<T extends {
__anyHack: unknown;
}>(value: T): boolean;
declare function isArrayLikeObject(value: AnyFunction | string | boolean | number | null | undefined): value is never;
declare function isArrayLikeObject(value: unknown): value is object & {
length: number;
};
/** ----------------------------------------------------------
* * ***Type guard: `isBigInt`.***
* ----------------------------------------------------------
* **Checks if a value is of type **[`BigInt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt)**.**
* - **Behavior:**
* - Uses `typeof value === "bigint"` for strict type checking.
* - Supports TypeScript type narrowing with `value is bigint`.
* - Returns `false` for `BigInt` object (object-wrapped), e.g:
* - `Object(BigInt(123))`.
* @param {*} value - The value to check.
* @returns {boolean} Return `true` if value is a primitive bigint.
* @example
* isBigInt(123n);
* // ➔ true
* isBigInt(BigInt(123));
* // ➔ true
* isBigInt("123");
* // ➔ false
* isBigInt(Object(BigInt(1)));
* // ➔ false
*/
declare const isBigInt: (value: unknown) => value is bigint;
/** ----------------------------------------------------------
* * ***Type guard: `isBoolean`.***
* ----------------------------------------------------------
* **Checks if a value is of type **[`boolean`](https://developer.mozilla.org/en-US/docs/Glossary/Boolean/JavaScript)**.**
* @param {*} value - The value to check.
* @returns {boolean} Returns `true` if the value is a `boolean`, otherwise `false`.
* @example
* isBoolean(true); // ➔ true
* isBoolean(false); // ➔ true
* isBoolean("true"); // ➔ false
*/
declare const isBoolean: (value: unknown) => value is boolean;
/** ----------------------------------------------------
* * ***Type guard: `isBooleanObject`.***
* ----------------------------------------------------
* **Checks if a value is a **`Boolean` object wrapper**
* (`new Boolean(...)`), not a primitive boolean.**
* @param {*} value The value to check.
* @returns {value is Boolean} Returns `true` if `value` is a `Boolean` object.
* @example
* isBooleanObject(new Boolean(true));
* // ➔ true
* isBooleanObject(true);
* // ➔ false
*/
declare function isBooleanObject(value: unknown): value is Boolean;
/** ----------------------------------------------------
* * ***Type guard: `isBuffer`.***
* ----------------------------------------------------------
* **Checks if a value is a *****{@link Buffer | `Node.js - Buffer`}***** instance.**
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a `Buffer`, else `false`.
* @example
* isBuffer(new Buffer(2));
* // ➔ true
* isBuffer(Buffer.alloc(10));
* // ➔ true
* isBuffer(Buffer.from('foo'));
* // ➔ true
* isBuffer([]);
* // ➔ false
* isBuffer('a string');
* // ➔ false
* isBuffer(new Uint8Array(1024));
* // ➔ false
*/
declare const isBuffer: (value: unknown) => value is Buffer;
/** -----------------------------------------------------------
* * ***Predicate: `isCurrencyLike`.***
* -----------------------------------------------------------
* **Determines if the given `input` can be interpreted as a currency-like number,
* using the same **multi-locale parsing logic** as ***`parseCurrencyString`***.**
* - **Highlights:**
* - *Supports strings or numbers like:*
* - `"15.000,10"` ***(European)***.
* - `"15,000.10"` ***(US)***.
* - `"15'000.10"` ***(Swiss)***.
* - `"15 000,10"` ***(French)***.
* - `"Rp 15.000,10"` or `"$15,000.10"`.
* - Also accepts simple numbers (`15300.95`).
* - **ℹ️ Note:**
* - Uses the same core logic as
* ***`parseCurrencyString`*** but
* just checks if a final parsed float is sensible.
* @param {*} input - The input value to check.
* @returns {boolean} Return `true` if it can be reasonably parsed into a currency-like number, `false` otherwise.
* @example
* isCurrencyLike(15300.95);
* // ➔ true
* isCurrencyLike("$15,000.10");
* // ➔ true
* isCurrencyLike("(15'000.10)");
* // ➔ true
* isCurrencyLike("Rp 15.000,10");
* // ➔ true
* isCurrencyLike("");
* // ➔ false
* isCurrencyLike("abc");
* // ➔ false
*/
declare const isCurrencyLike: (input: unknown) => boolean;
type isDateOptions = {
/** * ***Skip the validity check (`!isNaN(date.getTime())`).***
*
* When `true`, the function only checks that the value is an
* instance of `Date` without verifying that it represents a valid
* date value, default: `false`.
*
* @default false
*/
skipInvalidDate?: boolean;
};
/** ----------------------------------------------------------
* * ***Type guard: `isDate`.***
* ----------------------------------------------------------
* **Determines whether the given `value` is a real, valid JavaScript
* **[`Date`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date)** object.**
* - **Behavior:**
* - Returns **true** only if:
* - `value` is an instance of `Date`.
* - and, unless `options.skipInvalidDate` is `true`,
* the underlying time value is valid (`!isNaN(value.getTime())`).
* - Returns **false** for:
* - non-Date values (strings, numbers, etc.).
* - `Date` instances that represent an invalid time value
* (e.g. `new Date("bad")`), unless skipping is enabled.
* @param {*} value - The value to check.
* @param {isDateOptions} [options] - Optional settings.
* @returns {boolean} Return `true` if value is a valid Date object.
* @example
* isDate(new Date());
* // ➜ true
* isDate(new Date("invalid"));
* // ➜ false
* isDate("2024-01-01");
* // ➜ false
*
* // Skipping validity check:
* isDate(new Date("invalid"), { skipInvalidDate: true });
* // ➜ true
*/
declare const isDate: (value: unknown, options?: isDateOptions) => value is Date;
/** ----------------------------------------------------------
* * ***Predicate: `isDeepEqual`.***
* ----------------------------------------------------------
* **Performs a deep equality check between two values.**
* - **Behavior:**
* - Compares nested `arrays`, `objects`, `Dates`, `RegExp`, `NaN`, `Symbols`,
* `Set`, and `Map`.
* - Handles special cases:
* - `NaN` is considered equal to `NaN`.
* - `Date` objects are equal if `.getTime()` is equal.
* - `RegExp` objects are equal if `.toString()` is equal.
* - `Symbol("x")` and `Symbol("x")` are treated equal if
* `.toString()` matches.
* - `Set` and `Map` are deeply compared by content (order-insensitive).
* - **ℹ️ Note:**
* - Does not support circular references.
* @param {*} a - First value to compare.
* @param {*} b - Second value to compare.
* @returns {boolean} `true` if both values are deeply equal, otherwise `false`.
* @example
* // ✅ Primitives
* isDeepEqual(1, 1);
* // ➔ true
* isDeepEqual(NaN, NaN);
* // ➔ true
* isDeepEqual("hello", "world");
* // ➔ false
*
* // ✅ Objects
* isDeepEqual({ x: 1 }, { x: 1 });
* // ➔ true
* isDeepEqual({ x: 1 }, { y: 1 });
* // ➔ false
*
* // ✅ Arrays
* isDeepEqual([1, 2], [1, 2]);
* // ➔ true
* isDeepEqual([1, 2], [2, 1]);
* // ➔ false
*
* // ✅ Dates
* isDeepEqual(new Date(123), new Date(123));
* // ➔ true
*
* // ✅ Sets
* isDeepEqual(new Set([1, 2]), new Set([2, 1]));
* // ➔ true
*
* // ✅ Maps
* isDeepEqual(new Map([["a", 1]]), new Map([["a", 1]]));
* // ➔ true
*
* // ❌ Different types
* isDeepEqual(1, "1");
* // ➔ false
*/
declare const isDeepEqual: (a: unknown, b: unknown) => boolean;
/** ----------------------------------------------------
* * ***Type guard: `isElement`.***
* ----------------------------------------------------------
* **Checks if `value` is likely a
* **[`DOM Element`](https://developer.mozilla.org/en-US/docs/Web/API/Element)**.**
* @template T - The type of the value being checked.
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is extends instance of **[`Element`](https://developer.mozilla.org/en-US/docs/Web/API/Element)**, else `false`.
* @example
* isElement(document.body);
* // ➔ true
* isElement(document.createElement("div"));
* // ➔ true
* isElement('<body>');
* // ➔ false
* isElement(document);
* // ➔ false
* isElement({ tagName: "DIV" });
* // ➔ false
*/
declare function isElement(value: []): value is [];
declare function isElement<T extends Element>(value: T): value is T;
declare function isElement(value: unknown): value is Element;
/**
* -------------------------------------------------------------------
* * ***Array-like structure interface.***
* -------------------------------------------------------------------
* **Represents objects with indexed elements and a `length` property,
* similar to arrays, but not necessarily full Array instances.**
* @template T The type of elements stored in the array-like object.
* @example
* ```ts
* function logArrayLike<T>(items: ArrayLike<T>) {
* for (let i = 0; i < items.length; i++) {
* console.log(items[i]);
* }
* }
*
* const myNodeList: ArrayLike<Element> = document.querySelectorAll("div");
* logArrayLike(myNodeList);
* ```
*/
interface ArrayLike<T> {
/** * ***Number of elements in the array-like object.*** */
readonly length: number;
/** * ***Indexed access to elements.*** */
readonly [n: number]: T;
}
/** -------------------------------------------------------------------
* * ***Represents an object with no allowed properties.***
* -------------------------------------------------------------------
* **Useful for cases where you want to ensure a type has **no keys**.**
* @template T - The base type to convert into an empty object type.
* @example
* ```ts
* type Test = EmptyObject<{ a: number }>;
* // ➔ { a?: never }
* ```
*/
type EmptyObject<T> = {
[K in keyof T]?: never;
};
/** -------------------------------------------------------------------
* * ***Conditional empty object type.***
* -------------------------------------------------------------------
* **Produces `EmptyObject<T>` only if it is assignable to `T`.**
* @template T - The base type to check.
* @example
* ```ts
* type Test = EmptyObjectOf<{ a: number }>;
* // ➔ { a?: never } | never depending on assignability
* ```
*/
type EmptyObjectOf<T> = EmptyObject<T> extends T ? EmptyObject<T> : never;
/** -------------------------------------------------------------------
* * ***List type alias.***
* -------------------------------------------------------------------
* **Represents any array-like structure.**
* @template T - The type of elements in the list.
* @example
* ```ts
* const arr: List<number> = [1, 2, 3];
* const nodeList: List<Element> = document.querySelectorAll("div");
* ```
*/
type List<T> = ArrayLike<T>;
/** ----------------------------------------------------
* * ***Predicate: `isEmpty`.***
* ----------------------------------------------------------
* **Checks if `value` is an empty object, collection, map, or set.**
* - **Behavior:**
* - **Objects** are empty if they have no own enumerable string keyed properties.
* - **Array-like values** (arrays, strings, `arguments`, typed arrays, buffers)
* are empty if their `length` is `0`.
* - **Maps** and **Sets** are empty if their `size` is `0`.
* - **Booleans**, **numbers** (including `NaN`), **symbols**, and `null`/
* `undefined` are treated as empty.
* - **Functions** are considered empty if they have no own enumerable keys.
* - **ℹ️ Note:**
* - For more `Strict`, you can use
* ***`isEmptyValue` utility function*** instead.
* @template T - The type of the value being checked.
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is empty, else `false`.
* @example
* isEmpty(null);
* // ➔ true
* isEmpty(true);
* // ➔ true
* isEmpty(false);
* // ➔ true
* isEmpty(1);
* // ➔ true
* isEmpty(0);
* // ➔ true
* isEmpty(Symbol("x"));
* // ➔ true
* isEmpty(() => {});
* // ➔ true
* isEmpty("");
* // ➔ true
* isEmpty(" ");
* // ➔ false
* isEmpty([1, 2, 3]);
* // ➔ false
* isEmpty({ 'a': 1 });
* // ➔ false
*/
declare function isEmpty<T extends {
__trapAny: any;
}>(value?: T): boolean;
declare function isEmpty(value: string): value is "";
declare function isEmpty(value: Map<any, any> | Set<any> | List<any> | null | undefined): boolean;
declare function isEmpty(value: object): boolean;
declare function isEmpty<T extends object>(value: T | null | undefined): value is EmptyObjectOf<T> | null | undefined;
declare function isEmpty(value: any): boolean;
/** ----------------------------------------------------------
* * ***Predicate: `isEmptyArray`.***
* ----------------------------------------------------------
* **Checks whether a given value is an empty array.**
* - **Behavior:**
* - Non-array inputs are considered ***`empty`*** ***(defensive strategy)***.
* @param {*} [value] - The value to check.
* @returns {boolean} Returns `true` if it's ***not an array*** or ***an empty-array***.
* @example
* isEmptyArray([]); // ➔ true
* isEmptyArray([1, 2, 3]); // ➔ false
* isEmptyArray("not an array"); // ➔ true
* isEmptyArray(null); // ➔ true
* isEm