/** @Description: 数据类型判断* @Author: huhaonan@sics.ac.cn* @Date: 2021-12-10 17:24:17* @LastEditors: huhaonan@sics.ac.cn* @LastEditTime: 2022-01-07 10:45:21*/const toString = Object.prototype.toStringexport function isType(value: unknown, type: string) { return toString.call(value) === `[object ${type}]`}// 提取数据原始类型export function getType(value: unknown): string { return toString .call(value) .replace(/^\[object /, '') .replace(/]$/, '')}// 提取数据原始类型const toRawType = (value) => { return Object.prototype.toString.call(value).slice(8, -1)} // 示例 toRawType(''); 'String' toRawType([]); 'Array'// 是否为原始数据类型export function isPrimitive(value: unknown) { return ( typeof value === 'string' || typeof value === 'number' || // $flow-disable-line typeof value === 'symbol' || typeof value === 'boolean' )}export function isNull(value: unknown): value is null { return value === null}export function isDef<T = unknown>(value?: T): value is T { return typeof value !== 'undefined'}export function isUndefined<T = unknown>(value?: T): value is T { return value === undefined}export function isNil(value: any): value is null | undefined { /** * isNil(null) => true * isNil() => true */ return value === null || value === undefined}export function isNullAndUnDef(value: unknown): value is null | undefined { return isUndefined(value) && isNull(value)}export function isNullOrUnDef(value: unknown): value is null | undefined { return isUndefined(value) || isNull(value)}export function isBoolean(value: unknown): value is boolean { return isType(value, 'Boolean')}export function isNumber(value: unknown): value is number { return isType(value, 'Number')}//是否整数export const isInteger = Number.isInteger? Number.isInteger: function (num: any): boolean { return isNumber(num) && num % 1 === 0}// 是否正数export function isPositive(num: any): boolean { return isNumber(num) && num > 0}// 是否负数export function isNegative(num: unknown): boolean { return isNumber(num) && num < 0}// 是否偶数export function isEven(num: unknown): boolean { return isNumber(num) && num % 2 === 0}// 是否奇数export function isOdd(num: any): boolean { return isNumber(num) && num % 2 !== 0}export function isDecimal(num: any): boolean { return isNumber(num) && num % 1 !== 0}export function isString(value: unknown): value is string { return isType(value, 'String')}// isIntegerKey 判断是不是数字型的字符串export const isIntegerKey = (key) => isString(key) && key !== 'NaN' && key[0] !== '-' && '' + parseInt(key, 10) === key;// 例子:// isIntegerKey('a'); // false// isIntegerKey('0'); // true// isIntegerKey('011'); // false// isIntegerKey('11'); // true// isIntegerKey('-11'); // false// isIntegerKey(11); // false// isIntegerKey('NaN'); // false// 引用数据类型export function isArray(value: any): value is Array<any> { return value && Array.isArray(value)}// 是否类数组结构export function isArrayLike(value: any): boolean { /** * isArrayLike([1, 2, 3]) => true * isArrayLike(document.body.children) => true * isArrayLike('abc') => true * isArrayLike(Function) => false */ return value !== null && typeof value !== 'function' && isFinite(value.length)}export interface ObjectType<T> { [key: string]: T}// export function isObject(value: any): value is Record<any, any> {// return value !== null && isType(value, 'Object')// }export function isObject<T = any>(value: any): value is T { /** * isObject({}) => true * isObject([1, 2, 3]) => true * isObject(Function) => true * isObject(null) => false */ const type = typeof value return (value !== null && type === 'object') || type === 'function'}export function isObjectLike(value: any): value is ObjectType<any> { /** * isObjectLike({}) => true * isObjectLike([1, 2, 3]) => true * isObjectLike(Function) => false * isObjectLike(null) => false */ return value !== null && typeof value === 'object'}export function isPrototype(value: any): boolean { const Ctor = value && value.constructor const proto = (typeof Ctor === 'function' && Ctor.prototype) || Object.prototype return value === proto}export function isFunction(value: unknown) { return typeof value === 'function'}/*** 是否是参数类型** @param {Object} value 测试的值* @return {Boolean}*/export function isArguments(value: any): boolean { return isType(value, 'Arguments')}// export function isEmpty<T = unknown>(value: T): value is T {// if (isArray(value) || isString(value)) {// return value.length === 0// }// if (value instanceof Map || value instanceof Set) {// return value.size === 0// }// if (isObject(value)) {// return Object.keys(value).length === 0// }// return false// }/*** @Description: 是否为空* @param {any} value*/export function isEmpty(value: any): boolean { /** * isEmpty(null) => true * isEmpty() => true * isEmpty(true) => true * isEmpty(1) => true * isEmpty([1, 2, 3]) => false * isEmpty('abc') => false * isEmpty({ a: 1 }) => false */ const hasOwnProperty = Object.prototype.hasOwnProperty if (isNil(value)) { return true } if (isArrayLike(value)) { return !value.length } const type = getType(value) if (type === 'Map' || type === 'Set') { return !value.size } if (isPrototype(value)) { return !Object.keys(value).length } for (const key in value) { if (hasOwnProperty.call(value, key)) { return false } } return true}export function isRegExp(value: unknown): value is RegExp { return isType(value, 'RegExp')}export function isDate(value: unknown): value is Date { return isType(value, 'Date')}export function isFormData(val: unknown) { return typeof FormData !== 'undefined' && val instanceof FormData}export function isPromise<T = any>(value: unknown): value is Promise<T> { return ( isType(value, 'Promise') && isObject(value) && isFunction(value.then) && isFunction(value.catch) )}export function isError(value: any): value is Error { return isType(value, 'Error')}/*** @Description: 两个数据是否相同* @param {any} value* @param {any} other*/export function isEqual(value: any, other: any): boolean { if (value === other) { return true } if (!value || !other) { return false } if (isString(value) || isString(other)) { return false } if (isArrayLike(value) || isArrayLike(other)) { if (value.length !== other.length) { return false } let rst = true for (let i = 0; i < value.length; i++) { rst = isEqual(value[i], other[i]) if (!rst) { break } } return rst } if (isObjectLike(value) || isObjectLike(other)) { const valueKeys = Object.keys(value) const otherKeys = Object.keys(other) if (valueKeys.length !== otherKeys.length) { return false } let rst = true for (let i = 0; i < valueKeys.length; i++) { rst = isEqual(value[valueKeys[i]], other[valueKeys[i]]) if (!rst) { break } } return rst } return false}/*** @Description: 两个数据是否相同,不依赖其他函数,来自https://www.30secondsofcode.org/js/s/equals/* @param {any} value* @param {any} other*/const equals = (a: any, b: any): boolean => { if (a === b) return true; if (a instanceof Date && b instanceof Date) return a.getTime() === b.getTime(); if (!a || !b || (typeof a !== "object" && typeof b !== "object")) return a === b; if (a.prototype !== b.prototype) return false; const keys = Object.keys(a); if (keys.length !== Object.keys(b).length) return false; return keys.every((k) => equals(a[k], b[k]));};export function isWindow(value: any): value is Window { return typeof window !== 'undefined' && isType(value, 'Window')}// export function isElement(value: unknown): value is Element {// return isObject(value) && !!value.tagName// }/*** 判断是否HTML元素* @return {Boolean} 是否HTML元素*/export function isElement(o: any): boolean { return o instanceof Element || o instanceof HTMLDocument}export const isServer = typeof window === 'undefined'export const isClient = !isServerexport function isUrl(path: string): boolean { const reg = /(((^https?:(?:\/\/)?)(?:[-;:&=+$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=+$,\w]+@)[A-Za-z0-9.-]+)((?:\/[+~%/.\w-_]*)?\??(?:[-+=&;%@.\w_]*)#?(?:[\w]*))?)$/ return reg.test(path)}