UNPKG

zent

Version:

一套前端设计语言和基于React的实现

53 lines (45 loc) 1.77 kB
/** * copied from https://github.com/alexreardon/memoize-one */ export type EqualityFn = (newArgs: unknown[], lastArgs: unknown[]) => boolean; const shallowEqual = (newValue: unknown, oldValue: unknown): boolean => newValue === oldValue; const simpleIsEqual: EqualityFn = ( newArgs: unknown[], lastArgs: unknown[] ): boolean => newArgs.length === lastArgs.length && newArgs.every((newArg: unknown, index: number): boolean => shallowEqual(newArg, lastArgs[index]) ); // <ResultFn: (...Array<any>) => mixed> // The purpose of this typing is to ensure that the returned memoized // function has the same type as the provided function (`resultFn`). // ResultFn: Generic type (which is the same as the resultFn). // (...Array<any>): Accepts any length of arguments - and they are not checked // mixed: The result can be anything but needs to be checked before usage // eslint-disable-next-line @typescript-eslint/ban-types export default function <F extends Function>( resultFn: F, isEqual: EqualityFn = simpleIsEqual ): F { let lastThis: unknown; let lastArgs: unknown[] = []; let lastResult: unknown; let calledOnce = false; // breaking cache when context (this) or arguments change const result = function (...newArgs: unknown[]) { if (calledOnce && lastThis === this && isEqual(newArgs, lastArgs)) { return lastResult; } // Throwing during an assignment aborts the assignment: https://codepen.io/alexreardon/pen/RYKoaz // Doing the lastResult assignment first so that if it throws // nothing will be overwritten lastResult = resultFn.apply(this, newArgs); calledOnce = true; lastThis = this; lastArgs = newArgs; return lastResult; }; return result as unknown as F; }