From bbf7f3d7ea558353da133eb86b3d86d988eca528 Mon Sep 17 00:00:00 2001 From: EnixCoda Date: Sun, 5 Jun 2022 02:46:29 +0800 Subject: [PATCH] feat: is equal --- src/utils/is.ts | 73 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/src/utils/is.ts b/src/utils/is.ts index 9ea15f4..b6062e5 100644 --- a/src/utils/is.ts +++ b/src/utils/is.ts @@ -1,4 +1,77 @@ +type Primitive = string | number | boolean | null | undefined + +const equal = { + type: (a: unknown, b: unknown) => getType(a) === getType(b), + unknown(a: unknown, b: unknown) { + const type = getType(a) + if (!equal.primitive(type, getType(b))) return false + switch (type) { + case 'array': + if (!equal.array(a as unknown[], b as unknown[])) return false + break + case 'object': + if (!equal.object(a as Record, b as Record)) return false + break + case 'date': + case 'function': + case 'regexp': + case 'symbol': + if (!equal.primitive(`${a}`, `${b}`)) return false + break + default: + if (!equal.primitive(a as Primitive, b as Primitive)) return false + } + return true + }, + primitive: (a: T, b: T) => a === b, + array(a: unknown[], b: unknown[]) { + if (a.length !== b.length) return false + const length = a.length + for (let i = 0; i < length; i++) if (!equal.unknown(a[i], b[i])) return false + return true + }, + object(a: Record, b: Record) { + if (Object.keys(a).length !== Object.keys(b).length) return false + }, +} + +const shallowEqual = { + array(a: unknown[], b: unknown[]) { + if (a.length !== b.length) return false + const length = a.length + for (let i = 0; i < length; i++) if (a[i] !== b[i]) return false + return true + }, +} + +function getType(a: unknown) { + switch (typeof a) { + case 'boolean': + return 'boolean' + case 'function': + return 'function' + case 'number': + return 'number' + case 'string': + return 'string' + case 'symbol': + return 'symbol' + case 'undefined': + return 'undefined' + case 'object': + if (a === null) return 'null' + if (Array.isArray(a)) return 'array' + if (a instanceof Date) return 'date' + if (a instanceof RegExp) return 'regexp' + return 'object' + default: + return 'unknown' + } +} + export const is = { + equal, + shallowEqual, boolean: (d: unknown): d is boolean => typeof d === 'boolean', number: (d: unknown): d is number => typeof d === 'number', string: (d: unknown): d is string => typeof d === 'string',