import type { AnyFunctionOfReturn, BooleanNot, CastBoolean } from "#Source/type/index.ts" /** * @description Convert any value to a boolean. * * @example * ``` * // Expect: true * const example1 = booleanFrom(1) * // Expect: false * const example2 = booleanFrom(0) * ``` * * @see {@link https://developer.mozilla.org/en-US/docs/Glossary/Truthy} * @see {@link https://developer.mozilla.org/en-US/docs/Glossary/Falsy} */ export const booleanFrom = (value: unknown): boolean => Boolean(value) /** * @description Invert a boolean value. * * @example * ``` * // Expect: false * const example1 = booleanNot(true) * // Expect: true * const example2 = booleanNot(false) * ``` * * @see {@link https://en.wikipedia.org/wiki/Logic_gate} */ export function booleanNot(b: true): false export function booleanNot(b: false): true // catch all overload, used in `pipe` or `compose` or likewise situations. export function booleanNot(b: boolean): boolean export function booleanNot(b: unknown): boolean export function booleanNot(b: unknown): boolean { return !booleanFrom(b) } /** * @description Perform logical AND. * * @example * ``` * // Expect: false * const example1 = booleanAnd(true, false) * // Expect: true * const example2 = booleanAnd(true, true) * ``` * * @see {@link https://en.wikipedia.org/wiki/Logic_gate} */ export const booleanAnd = (x: unknown, y: unknown): boolean => booleanFrom(x) && booleanFrom(y) /** * @description Perform logical OR. * * @example * ``` * // Expect: true * const example1 = booleanOr(true, false) * // Expect: false * const example2 = booleanOr(false, false) * ``` * * @see {@link https://en.wikipedia.org/wiki/Logic_gate} */ export const booleanOr = (x: unknown, y: unknown): boolean => booleanFrom(x) || booleanFrom(y) /** * @description Perform logical NAND. * * @example * ``` * // Expect: true * const example1 = booleanNand(true, false) * // Expect: false * const example2 = booleanNand(true, true) * ``` * * @see {@link https://en.wikipedia.org/wiki/Logic_gate} */ export const booleanNand = (x: unknown, y: unknown): boolean => !booleanAnd(x, y) /** * @description Perform logical NOR. * * @example * ``` * // Expect: false * const example1 = booleanNor(true, false) * // Expect: true * const example2 = booleanNor(false, false) * ``` * * @see {@link https://en.wikipedia.org/wiki/Logic_gate} */ export const booleanNor = (x: unknown, y: unknown): boolean => !booleanOr(x, y) /** * @description Perform logical XOR. * * @example * ``` * // Expect: true * const example1 = booleanXor(true, false) * // Expect: false * const example2 = booleanXor(true, true) * ``` * * @see {@link https://en.wikipedia.org/wiki/Logic_gate} */ export const booleanXor = (x: unknown, y: unknown): boolean => booleanFrom(x) !== booleanFrom(y) /** * @description Perform logical XNOR. * * @example * ``` * // Expect: false * const example1 = booleanXnor(true, false) * // Expect: true * const example2 = booleanXnor(true, true) * ``` * * @see {@link https://en.wikipedia.org/wiki/Logic_gate} */ export const booleanXnor = (x: unknown, y: unknown): boolean => !booleanXor(x, y) export type BooleanInvertFunctionReturn> = // oxlint-disable-next-line no-explicit-any FN extends (...args: any[]) => infer R ? (...args: Parameters) => BooleanNot> : never /** * @description Create a complement function that inverts a boolean-returning function. * * @example * ``` * const isEven = (value: number) => value % 2 === 0 * const isOdd = booleanComplement(isEven) * // Expect: true * const example1 = isOdd(3) * // Expect: false * const example2 = isOdd(4) * ``` */ export const booleanComplement = >( fn: FN, ): BooleanInvertFunctionReturn => // oxlint-disable-next-line no-explicit-any no-unsafe-argument ((...args: any[]) => booleanNot(fn(...args))) as any as BooleanInvertFunctionReturn /** * @description Check whether the value is truthy. * * @example * ``` * // Expect: true * const example1 = booleanIsTruthy("ok") * // Expect: false * const example2 = booleanIsTruthy("") * ``` * * @see {@link https://developer.mozilla.org/en-US/docs/Glossary/Truthy} * @see {@link booleanIsFalsy} */ export const booleanIsTruthy = (v: unknown): boolean => booleanFrom(v) /** * @description Check whether the value is falsy. * * @example * ``` * // Expect: true * const example1 = booleanIsFalsy(0) * // Expect: false * const example2 = booleanIsFalsy("0") * ``` * * @see {@link https://developer.mozilla.org/en-US/docs/Glossary/Falsy} * @see {@link booleanIsTruthy} */ export const booleanIsFalsy = (v: unknown): boolean => !booleanIsTruthy(v)