@@ -1634,31 +1634,56 @@ namespace ts {
16341634 } ;
16351635 }
16361636
1637- export function memoizeOne < ArgsT extends unknown [ ] , ReturnT > ( callback : ( ...args : ArgsT ) => ReturnT ) : typeof callback & { clear : ( ) => void } {
1637+ interface MemoizedFunction < ArgsT extends unknown [ ] , ReturnT > {
1638+ ( ...args : ArgsT ) : ReturnT ;
1639+ /** Potentially reads from the cache, but does not write to it. */
1640+ withoutCachingResult ( ...args : ArgsT ) : ReturnT ;
1641+ clear ( ) : void ;
1642+ }
1643+
1644+ export function memoizeOne < ArgsT extends unknown [ ] , ReturnT > (
1645+ callback : ( ...args : ArgsT ) => ReturnT ,
1646+ shouldUseCachedValue : ( prevArgs : ArgsT , args : ArgsT ) => boolean = argsAreEqual ,
1647+ ) : MemoizedFunction < ArgsT , ReturnT > {
16381648 let value : ReturnT ;
16391649 let cachedArgs : ArgsT ;
16401650 runMemoized . clear = ( ) => {
16411651 value = undefined ! ;
16421652 cachedArgs = undefined ! ;
16431653 } ;
1654+ runMemoized . withoutCachingResult = ( ...args : ArgsT ) => {
1655+ const lastArgs = cachedArgs ;
1656+ const lastValue = value ;
1657+ const newValue = runMemoized ( ...args ) ;
1658+ cachedArgs = lastArgs ;
1659+ value = lastValue ;
1660+ return newValue ;
1661+ } ;
16441662 return runMemoized ;
16451663
16461664 function runMemoized ( ...args : ArgsT ) {
1647- const length = args . length ;
1648- if ( cachedArgs && cachedArgs . length === length ) {
1649- for ( let i = 0 ; i < length ; i ++ ) {
1650- if ( args [ i ] !== cachedArgs [ i ] ) {
1651- cachedArgs = args ;
1652- return value = callback ( ...args ) ;
1653- }
1654- }
1665+ if ( cachedArgs && shouldUseCachedValue ( cachedArgs , args ) ) {
1666+ cachedArgs = args ;
16551667 return value ;
16561668 }
16571669 cachedArgs = args ;
16581670 return value = callback ( ...args ) ;
16591671 }
16601672 }
16611673
1674+ function argsAreEqual < T extends unknown [ ] > ( prevArgs : T , args : T ) : boolean {
1675+ const length = args . length ;
1676+ if ( prevArgs && prevArgs . length === length ) {
1677+ for ( let i = 0 ; i < length ; i ++ ) {
1678+ if ( args [ i ] !== prevArgs [ i ] ) {
1679+ return false ;
1680+ }
1681+ }
1682+ return true ;
1683+ }
1684+ return false ;
1685+ }
1686+
16621687 /**
16631688 * High-order function, composes functions. Note that functions are composed inside-out;
16641689 * for example, `compose(a, b)` is the equivalent of `x => b(a(x))`.
0 commit comments