diff --git a/src/index.js b/src/index.js index ad0fb57..964c7b6 100644 --- a/src/index.js +++ b/src/index.js @@ -14,36 +14,36 @@ const simpleIsEqual: EqualityFn = ( shallowEqual(newArg, lastArgs[index]), ); -// 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). -// (...any[]): Accepts any length of arguments - and they are not checked -// mixed: The result can be anything but needs to be checked before usage -export default function mixed>( - resultFn: ResultFn, +// Type TArgs (arguments type) and TRet (return type) as generics to ensure that the +// returned function (`memoized`) has the same type as the provided function (`inputFn`). +// +// `mixed` means that the result can be anything but needs to be checked before usage. +// As opposed to `any`, it does not compromise type-safety. +// See https://flow.org/en/docs/types/mixed/ for more. +export default function memoizeOne( + inputFn: (...TArgs) => TRet, isEqual?: EqualityFn = simpleIsEqual, -): ResultFn { +): (...TArgs) => TRet { let lastThis: mixed; - let lastArgs: mixed[] = []; - let lastResult: mixed; + let lastArgs: ?TArgs; + let lastResult: TRet; // not ?TRet because TRet must include undefined | null let calledOnce: boolean = false; // breaking cache when context (this) or arguments change - const result = function(...newArgs: mixed[]) { - if (calledOnce && lastThis === this && isEqual(newArgs, lastArgs)) { + const memoized = function(...newArgs: TArgs): TRet { + 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); + lastResult = inputFn.apply(this, newArgs); calledOnce = true; lastThis = this; lastArgs = newArgs; return lastResult; }; - return (result: any); + return memoized; }