1. /*
    2. * @Description: 数据类型判断
    3. * @Author: huhaonan@sics.ac.cn
    4. * @Date: 2021-12-10 17:24:17
    5. * @LastEditors: huhaonan@sics.ac.cn
    6. * @LastEditTime: 2022-01-07 10:45:21
    7. */
    8. const toString = Object.prototype.toString
    9. export function isType(value: unknown, type: string) {
    10. return toString.call(value) === `[object ${type}]`
    11. }
    12. export function getType(value: unknown): string {
    13. return toString
    14. .call(value)
    15. .replace(/^\[object /, '')
    16. .replace(/]$/, '')
    17. }
    18. // 原始数据类型
    19. export function isPrimitive(value: unknown) {
    20. return (
    21. typeof value === 'string' ||
    22. typeof value === 'number' ||
    23. // $flow-disable-line
    24. typeof value === 'symbol' ||
    25. typeof value === 'boolean'
    26. )
    27. }
    28. export function isNull(value: unknown): value is null {
    29. return value === null
    30. }
    31. export function isDef<T = unknown>(value?: T): value is T {
    32. return typeof value !== 'undefined'
    33. }
    34. export function isUndefined<T = unknown>(value?: T): value is T {
    35. return value === undefined
    36. }
    37. export function isNil(value: any): value is null | undefined {
    38. /**
    39. * isNil(null) => true
    40. * isNil() => true
    41. */
    42. return value === null || value === undefined
    43. }
    44. export function isNullAndUnDef(value: unknown): value is null | undefined {
    45. return isUndefined(value) && isNull(value)
    46. }
    47. export function isNullOrUnDef(value: unknown): value is null | undefined {
    48. return isUndefined(value) || isNull(value)
    49. }
    50. export function isBoolean(value: unknown): value is boolean {
    51. return isType(value, 'Boolean')
    52. }
    53. export function isNumber(value: unknown): value is number {
    54. return isType(value, 'Number')
    55. }
    56. //是否整数
    57. export const isInteger = Number.isInteger
    58. ? Number.isInteger
    59. : function (num: any): boolean {
    60. return isNumber(num) && num % 1 === 0
    61. }
    62. // 是否正数
    63. export function isPositive(num: any): boolean {
    64. return isNumber(num) && num > 0
    65. }
    66. // 是否负数
    67. export function isNegative(num: unknown): boolean {
    68. return isNumber(num) && num < 0
    69. }
    70. // 是否偶数
    71. export function isEven(num: unknown): boolean {
    72. return isNumber(num) && num % 2 === 0
    73. }
    74. // 是否奇数
    75. export function isOdd(num: any): boolean {
    76. return isNumber(num) && num % 2 !== 0
    77. }
    78. export function isDecimal(num: any): boolean {
    79. return isNumber(num) && num % 1 !== 0
    80. }
    81. export function isString(value: unknown): value is string {
    82. return isType(value, 'String')
    83. }
    84. // 引用数据类型
    85. export function isArray(value: any): value is Array<any> {
    86. return value && Array.isArray(value)
    87. }
    88. // 是否类数组结构
    89. export function isArrayLike(value: any): boolean {
    90. /**
    91. * isArrayLike([1, 2, 3]) => true
    92. * isArrayLike(document.body.children) => true
    93. * isArrayLike('abc') => true
    94. * isArrayLike(Function) => false
    95. */
    96. return value !== null && typeof value !== 'function' && isFinite(value.length)
    97. }
    98. export interface ObjectType<T> {
    99. [key: string]: T
    100. }
    101. // export function isObject(value: any): value is Record<any, any> {
    102. // return value !== null && isType(value, 'Object')
    103. // }
    104. export function isObject<T = any>(value: any): value is T {
    105. /**
    106. * isObject({}) => true
    107. * isObject([1, 2, 3]) => true
    108. * isObject(Function) => true
    109. * isObject(null) => false
    110. */
    111. const type = typeof value
    112. return (value !== null && type === 'object') || type === 'function'
    113. }
    114. export function isObjectLike(value: any): value is ObjectType<any> {
    115. /**
    116. * isObjectLike({}) => true
    117. * isObjectLike([1, 2, 3]) => true
    118. * isObjectLike(Function) => false
    119. * isObjectLike(null) => false
    120. */
    121. return value !== null && typeof value === 'object'
    122. }
    123. export function isPrototype(value: any): boolean {
    124. const Ctor = value && value.constructor
    125. const proto =
    126. (typeof Ctor === 'function' && Ctor.prototype) || Object.prototype
    127. return value === proto
    128. }
    129. export function isFunction(value: unknown) {
    130. return typeof value === 'function'
    131. }
    132. /**
    133. * 是否是参数类型
    134. *
    135. * @param {Object} value 测试的值
    136. * @return {Boolean}
    137. */
    138. export function isArguments(value: any): boolean {
    139. return isType(value, 'Arguments')
    140. }
    141. // export function isEmpty<T = unknown>(value: T): value is T {
    142. // if (isArray(value) || isString(value)) {
    143. // return value.length === 0
    144. // }
    145. // if (value instanceof Map || value instanceof Set) {
    146. // return value.size === 0
    147. // }
    148. // if (isObject(value)) {
    149. // return Object.keys(value).length === 0
    150. // }
    151. // return false
    152. // }
    153. /**
    154. * @Description: 是否为空
    155. * @param {any} value
    156. */
    157. export function isEmpty(value: any): boolean {
    158. /**
    159. * isEmpty(null) => true
    160. * isEmpty() => true
    161. * isEmpty(true) => true
    162. * isEmpty(1) => true
    163. * isEmpty([1, 2, 3]) => false
    164. * isEmpty('abc') => false
    165. * isEmpty({ a: 1 }) => false
    166. */
    167. const hasOwnProperty = Object.prototype.hasOwnProperty
    168. if (isNil(value)) {
    169. return true
    170. }
    171. if (isArrayLike(value)) {
    172. return !value.length
    173. }
    174. const type = getType(value)
    175. if (type === 'Map' || type === 'Set') {
    176. return !value.size
    177. }
    178. if (isPrototype(value)) {
    179. return !Object.keys(value).length
    180. }
    181. for (const key in value) {
    182. if (hasOwnProperty.call(value, key)) {
    183. return false
    184. }
    185. }
    186. return true
    187. }
    188. export function isRegExp(value: unknown): value is RegExp {
    189. return isType(value, 'RegExp')
    190. }
    191. export function isDate(value: unknown): value is Date {
    192. return isType(value, 'Date')
    193. }
    194. export function isFormData(val: unknown) {
    195. return typeof FormData !== 'undefined' && val instanceof FormData
    196. }
    197. export function isPromise<T = any>(value: unknown): value is Promise<T> {
    198. return (
    199. isType(value, 'Promise') &&
    200. isObject(value) &&
    201. isFunction(value.then) &&
    202. isFunction(value.catch)
    203. )
    204. }
    205. export function isError(value: any): value is Error {
    206. return isType(value, 'Error')
    207. }
    208. /**
    209. * @Description: 两个数据是否相同
    210. * @param {any} value
    211. * @param {any} other
    212. */
    213. export function isEqual(value: any, other: any): boolean {
    214. if (value === other) {
    215. return true
    216. }
    217. if (!value || !other) {
    218. return false
    219. }
    220. if (isString(value) || isString(other)) {
    221. return false
    222. }
    223. if (isArrayLike(value) || isArrayLike(other)) {
    224. if (value.length !== other.length) {
    225. return false
    226. }
    227. let rst = true
    228. for (let i = 0; i < value.length; i++) {
    229. rst = isEqual(value[i], other[i])
    230. if (!rst) {
    231. break
    232. }
    233. }
    234. return rst
    235. }
    236. if (isObjectLike(value) || isObjectLike(other)) {
    237. const valueKeys = Object.keys(value)
    238. const otherKeys = Object.keys(other)
    239. if (valueKeys.length !== otherKeys.length) {
    240. return false
    241. }
    242. let rst = true
    243. for (let i = 0; i < valueKeys.length; i++) {
    244. rst = isEqual(value[valueKeys[i]], other[valueKeys[i]])
    245. if (!rst) {
    246. break
    247. }
    248. }
    249. return rst
    250. }
    251. return false
    252. }
    253. export function isWindow(value: any): value is Window {
    254. return typeof window !== 'undefined' && isType(value, 'Window')
    255. }
    256. // export function isElement(value: unknown): value is Element {
    257. // return isObject(value) && !!value.tagName
    258. // }
    259. /**
    260. * 判断是否HTML元素
    261. * @return {Boolean} 是否HTML元素
    262. */
    263. export function isElement(o: any): boolean {
    264. return o instanceof Element || o instanceof HTMLDocument
    265. }
    266. export const isServer = typeof window === 'undefined'
    267. export const isClient = !isServer
    268. export function isUrl(path: string): boolean {
    269. const reg =
    270. /(((^https?:(?:\/\/)?)(?:[-;:&=+$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=+$,\w]+@)[A-Za-z0-9.-]+)((?:\/[+~%/.\w-_]*)?\??(?:[-+=&;%@.\w_]*)#?(?:[\w]*))?)$/
    271. return reg.test(path)
    272. }