/* * @since 2020-11-04 11:12:36 * @author acrazing */ /** * Returns the first argument * @param v */ export const identity = (v: T) => v; /** * Check two objects is shallow equal or not * @param a * @param b */ export function shallowEqual(a: T, b: T): boolean { if (a === b) { return true; } const ka = Object.keys(a) as Array; if (ka.length !== Object.keys(b).length) { return false; } for (let i = 0; i < ka.length; i++) { if (!b.hasOwnProperty(ka[i]) || a[ka[i]] !== b[ka[i]]) { return false; } } return true; } /** * Copy properties from src function to dst function, and returns dst * * @param src * @param dst */ export function hoistMethod any>( src: M, dst: (...args: Parameters) => ReturnType, ): M { const copy = (name: PropertyKey) => { if (dst.hasOwnProperty(name)) { return; } Object.defineProperty(dst, name, Object.getOwnPropertyDescriptor(src, name)!); }; Object.getOwnPropertyNames(src).forEach(copy); Object.getOwnPropertySymbols?.(src).forEach(copy); return dst as M; } export const kAmosObject: unique symbol = typeof Symbol === 'function' ? Symbol('AMOS_OBJECT') : ('Symbol(AMOS_OBJECT)' as any); /** * A symbol indicates the object is a amos' object. */ export interface AmosObject { [kAmosObject]: K; } /** @internal */ export function defineAmosObject( key: K, obj: T, ): T & AmosObject { if (!obj.hasOwnProperty(kAmosObject)) { Object.defineProperty(obj, kAmosObject, { value: key }); } return obj as any; } /** * Check an object is an amos object or not * * @param key * @param o */ export function isAmosObject>( key: T[typeof kAmosObject], o: any, ): o is T { return !!o && o[kAmosObject] === key; } /** @internal */ export function strictEqual(a: T, b: T) { return a === b; } /** * Check two array is shallow equal or not * @param a * @param b */ export function arrayEqual>(a: T, b: T) { if (a.length !== b.length) { return false; } for (let i = 0; i < a.length; i++) { if (a[i] !== b[i]) { return false; } } return true; } /** @internal */ export function values(o: T): T[keyof T][] { return Object.keys(o).map((k) => o[k as keyof T]); } /** @internal */ export const isArray: (args: any) => args is any[] | readonly any[] = Array.isArray; export function config(this: T, options: object): T { return Object.assign(this, { options }); }