UNPKG

1.31 kBPlain TextView Raw
1import areInputsEqual from './are-inputs-equal';
2
3// Using ReadonlyArray<T> rather than readonly T as it works with TS v3
4export type EqualityFn = (newArgs: any[], lastArgs: any[]) => boolean;
5
6function memoizeOne<
7 // Need to use 'any' rather than 'unknown' here as it has
8 // The correct Generic narrowing behaviour.
9 ResultFn extends (this: any, ...newArgs: any[]) => ReturnType<ResultFn>
10>(resultFn: ResultFn, isEqual: EqualityFn = areInputsEqual): ResultFn {
11 let lastThis: unknown;
12 let lastArgs: unknown[] = [];
13 let lastResult: ReturnType<ResultFn>;
14 let calledOnce: boolean = false;
15
16 // breaking cache when context (this) or arguments change
17 function memoized(this: unknown, ...newArgs: unknown[]): ReturnType<ResultFn> {
18 if (calledOnce && lastThis === this && isEqual(newArgs, lastArgs)) {
19 return lastResult;
20 }
21
22 // Throwing during an assignment aborts the assignment: https://codepen.io/alexreardon/pen/RYKoaz
23 // Doing the lastResult assignment first so that if it throws
24 // nothing will be overwritten
25 lastResult = resultFn.apply(this, newArgs);
26 calledOnce = true;
27 lastThis = this;
28 lastArgs = newArgs;
29 return lastResult;
30 }
31
32 return memoized as ResultFn;
33}
34
35// default export
36export default memoizeOne;
37// named export
38export { memoizeOne };