Files
zero-fucks-given/packages/utils/src/is.ts
T

81 lines
2.6 KiB
TypeScript
Executable File

export const isUndef = (o: unknown): o is undefined | void => typeof o === 'undefined' || o === undefined;
export const isNull = (o: unknown): o is null => o === null;
export const isBool = (o: unknown): o is boolean => typeof o === 'boolean';
export const isNil = (o: unknown): o is null | undefined | void => isNull(o) || isUndef(o);
export function isStr<T extends string = string>(o: unknown): o is T {
return typeof o === 'string';
}
export const isNum = (o: unknown, isStringAllowed = false): o is number => {
const isNumType = typeof o === 'number';
if (!isStringAllowed) return isNumType;
return isNumType || (typeof o === 'string' && !isNaN(Number(o)) && o.trim() !== '');
};
export const isNumStr = (o: unknown): o is number | string => isNum(o, true);
export const isEven = (num: number): boolean => num % 2 === 0;
export const isOdd = (num: number): boolean => num % 2 !== 0;
type Func = (...args: any[]) => any;
export function isFunc<T extends Func = Func>(o: unknown): o is T {
return !(isNull(o) || isUndef(o)) && typeof o === 'function';
}
export function isArr<T extends unknown[] = unknown[]>(value: unknown): value is T {
return Array.isArray(value) as boolean;
}
export function isPureObj<T extends Record<string, any> = Record<string, any>>(o: unknown): o is T {
return !(isNull(o) || isUndef(o)) && typeof o === 'object' && !isArr(o) && !(o instanceof Map) && !(o instanceof Set);
}
/**
* Check if two objects are deeply equal.
*
* @param objA - The first object to compare.
* @param objB - The second object to compare.
* @returns A boolean indicating whether the objects are deeply equal.
*
* @example
* const obj1 = { a: 1, b: { c: 2 } };
* const obj2 = { a: 1, b: { c: 2 } };
* const isEqual = isDeepEqual(obj1, obj2);
* // isEqual: true
*/
export function isDeepEqual(objA: any, objB: any): boolean {
if (Object.is(objA, objB)) return true;
if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) return false;
if (objA.constructor !== objB.constructor) return false;
const keysA = Object.keys(objA);
const keysB = Object.keys(objB);
if (keysA.length !== keysB.length) return false;
const bHasOwnProperty = global.hasOwnProperty.bind(objB);
while (keysA.length > 0) {
const key: any = keysA.pop();
if (!bHasOwnProperty(key)) return false;
const a: unknown = objA[key];
const b: unknown = objB[key];
if (!Object.is(a, b)) {
if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) return false;
if (!isDeepEqual(a, b)) return false;
}
}
return true;
}