UNPKG

@ffsm/nullish

Version:
391 lines 12.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isNull = isNull; exports.isUndefined = isUndefined; exports.isNullish = isNullish; exports.isNotNullish = isNotNullish; exports.nullish = nullish; exports.chain = chain; exports.map = map; exports.until = until; exports.every = every; exports.some = some; exports.tryNull = tryNull; exports.hocTryNull = hocTryNull; exports.isNullishOrEmpty = isNullishOrEmpty; exports.coalesce = coalesce; exports.coalesceRight = coalesceRight; exports.swap = swap; /** * Checks if a value is null. * * This function uses a TypeScript type predicate to improve * type checking in conditional statements. * * @param value - The value to check * @returns `true` if the value is null, otherwise `false` * * @example * ```typescript * if (isNull(response.data)) { * // TypeScript knows response.data is null here * console.log('Null response received'); * } * ``` */ function isNull(value) { return value === null; } /** * Checks if a value is undefined. * * This function uses a TypeScript type predicate to improve * type checking in conditional statements. * * @param value - The value to check * @returns `true` if the value is undefined, otherwise `false` * * @example * ```typescript * if (isUndefined(response.meta)) { * // TypeScript knows response.meta is undefined here * console.log('No metadata available'); * } * ``` */ function isUndefined(value) { return value === undefined; } /** * Checks if a value is null or undefined. * * This function uses a TypeScript type predicate to improve * type checking in conditional statements. It leverages the * isNull and isUndefined functions for readable implementation. * * @param value - The value to check * @returns `true` if the value is null or undefined, otherwise `false` * * @example * ```typescript * if (isNullish(user.name)) { * // TypeScript knows user.name is null or undefined here * console.log('Name not provided'); * } else { * // TypeScript knows user.name is not null or undefined here * console.log('Hello, ' + user.name); * } * ``` */ function isNullish(value) { return isNull(value) || isUndefined(value); } /** * Type guard that checks if a value is neither null nor undefined. * @template T - The type of the value being checked * @param {T | null | undefined} value - The value to check * @returns {boolean} True if the value is neither null nor undefined * @example * if (isNotNullish(user)) { * // TypeScript knows user is not null or undefined here * console.log(user.name); * } */ function isNotNullish(value) { return !isNullish(value); } /** * Returns the input value if it's not null or undefined, * otherwise returns the provided default value. * * This function implements nullish checking using ternary operators, * with advanced type handling for better TypeScript integration. * * @param value - The value to check * @param defaultValue - The default value to return if `value` is null or undefined * @returns The input value if not null/undefined, otherwise the default value * * @typeParam Return - The expected return type * @typeParam Type - Type of the input value * @typeParam Reset - Type of the default value * * @example * ```typescript * // Basic usage * const username = nullish<string>(user.name, 'Anonymous User'); * * // Use in a data processing pipeline * const results = data * .map(item => nullish<number>(item.value, 0)) * .filter(value => value > 10); * * // With complex objects * const config = { * timeout: nullish<number>(userConfig.timeout, 1000), * retries: nullish<number>(userConfig.retries, 3) * }; * ``` */ function nullish(value, defaultValue) { return (isNullish(value) ? defaultValue : value); } /** * Chains multiple functions together, applying each one to the result of the previous function * only if the value is not nullish. * @template T - The type of the value being transformed * @param {T | null | undefined} value - The initial value * @param {...((value: T) => T)[]} fns - The functions to apply sequentially * @returns {T | null | undefined} The final transformed value, or the original nullish value if input was nullish * @example * const result = chain( * "Hello, World!", * (str) => str.toUpperCase(), * (str) => str.replace("WORLD", "TypeScript") * ); * // result: "HELLO, TYPESCRIPT!" */ function chain(value, ...fns) { return fns.reduce((result, fn) => (isNotNullish(value) ? fn(result) : result), value); } /** * Maps a value through a series of transformation functions, stopping if any intermediate * result is nullish. * @template T - The type of the input value * @template U - The type of the output value * @param {T | null | undefined} value - The initial value * @param {...((value: T) => U)[]} fns - The transformation functions to apply sequentially * @returns {U | null | undefined} The transformed value, or null/undefined if any step produced a nullish result * @example * const length = map( * "Hello, World!", * (str) => str.length * ); * // length: 13 */ function map(value, ...fns) { return fns.reduce((result, fn) => (isNullish(result) ? result : fn(result)), value); } /** * Processes a value through a series of functions until a non-nullish result is produced. * If the initial value is not nullish, it's returned immediately without applying any functions. * * @template T - The type of the value being processed * @param {T} value - The initial value to process * @param {...((value: T) => T)[]} fns - Functions to apply sequentially until a non-nullish result is found * @returns {T} The first non-nullish result, or the final value after all functions are applied * * @example * // Try different ways to get a valid value * const result = until( * null, // Start with null * () => localStorage.getItem('username'), // Try localStorage * () => sessionStorage.getItem('username'), // Try sessionStorage * () => 'guest' // Default to 'guest' if previous attempts return nullish * ); * // Returns first non-nullish value from the chain * * @example * // Skip processing if initial value is not nullish * const name = until( * user.name, // If this isn't nullish, other functions won't run * () => user.nickname, * () => 'Anonymous' * ); * // Returns user.name if it's not nullish * * @example * // Process until a condition is met * const validId = until( * '', // Start with empty string (nullish by isNotNullish definition) * () => generateId(), // Generate an ID * (id) => validateId(id) ? id : null // Return null if invalid, triggering next function * ); */ function until(value, ...fns) { if (isNotNullish(value)) { return value; } for (const fn of fns) { value = fn(value); if (isNotNullish(value)) { return value; } } return value; } /** * Checks if every element in an array is not nullish. * @param {unknown[]} value - The array to check * @returns {boolean} True if every element is not nullish * @example * const allValid = every([1, "string", {}, []]); * // allValid: true * * const hasNullish = every([1, null, "string"]); * // hasNullish: false */ function every(value) { return value.every(isNotNullish); } /** * Checks if at least one element in an array is not nullish. * @param {unknown[]} value - The array to check * @returns {boolean} True if at least one element is not nullish * @example * const hasValue = some([null, undefined, 1]); * // hasValue: true * * const allNullish = some([null, undefined]); * // allNullish: false */ function some(value) { return value.some(isNotNullish); } /** * Executes a function and returns its result, or null if an error is thrown. * @template T - The return type of the function * @param {() => T} fn - The function to execute * @returns {T | null} The result of the function, or null if an error was thrown * @example * const safeJsonParse = tryNull(() => JSON.parse('{"name": "John"}')); * // safeJsonParse: { name: "John" } * * const invalidJson = tryNull(() => JSON.parse('{"invalid": json}')); * // invalidJson: null */ function tryNull(fn) { try { return fn(); } catch (_a) { return null; } } /** * Higher-order function that wraps a function to catch errors and return null instead. * @template T - The return type of the function * @template Params - The parameter types of the function * @param {(...args: Params) => T} fn - The function to wrap * @returns {(...args: Params) => T | null} A new function that returns null on error * @example * const safeParse = hocTryNull(JSON.parse); * const result = safeParse('{"name": "John"}'); * // result: { name: "John" } * * const invalid = safeParse('{"invalid": json}'); * // invalid: null */ function hocTryNull(fn) { return (...args) => { try { return fn(...args); } catch (_a) { return null; } }; } /** * Checks if a value is nullish, an empty array, an empty object, or an empty string. * @param {unknown} value - The value to check * @returns {boolean} True if the value is nullish or empty * @example * isNullishOrEmpty(null); // true * isNullishOrEmpty(undefined); // true * isNullishOrEmpty([]); // true * isNullishOrEmpty({}); // true * isNullishOrEmpty(""); // true * isNullishOrEmpty(" "); // true * isNullishOrEmpty([1, 2]); // false * isNullishOrEmpty({ a: 1 }); // false * isNullishOrEmpty("Hello"); // false */ function isNullishOrEmpty(value) { if (isNullish(value)) { return true; } if (Array.isArray(value)) { return value.length === 0; } if (typeof value === 'object') { return Object.keys(value).length === 0; } if (typeof value === 'string') { return value.trim() === ''; } return false; } /** * Returns the first non-nullish value from the provided arguments, or null if all are nullish. * @template T - The type of the values being checked * @param {...(T | null | undefined)[]} values - The values to check * @returns {T | null} The first non-nullish value, or null if all are nullish * @example * const result = coalesce(null, undefined, 0, "hello"); * // result: 0 * * const allNullish = coalesce(null, undefined); * // allNullish: null */ function coalesce(...values) { for (const value of values) { if (isNotNullish(value)) { return value; } } return null; } /** * Returns the last non-nullish value from the provided arguments, or null if all are nullish. * @template T - The type of the values being checked * @param {...(T | null | undefined)[]} values - The values to check * @returns {T | null} The last non-nullish value, or null if all are nullish * @example * const result = coalesceRight(null, "hello", 0, undefined); * // result: 0 * * const allNullish = coalesceRight(null, undefined); * // allNullish: null */ function coalesceRight(...values) { for (let i = values.length - 1; i >= 0; i--) { if (isNotNullish(values[i])) { return values[i]; } } return null; } /** * Swaps null with undefined and vice versa. * @template T - The type of the value being swapped (must be null or undefined) * @param {T} value - The value to swap * @returns {null | undefined} The swapped value * @example * const value1 = swap(null); * // value1: undefined * * const value2 = swap(undefined); * // value2: null */ function swap(value) { return (isNull(value) ? undefined : null); } exports.default = { nullish, isNullish, isNull, isUndefined, isNotNullish, chain, map, until, every, some, tryNull, hocTryNull, isNullishOrEmpty, coalesce, coalesceRight, swap, }; //# sourceMappingURL=index.js.map