@@ -1634,31 +1634,56 @@ namespace ts {
1634
1634
} ;
1635
1635
}
1636
1636
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 > {
1638
1648
let value : ReturnT ;
1639
1649
let cachedArgs : ArgsT ;
1640
1650
runMemoized . clear = ( ) => {
1641
1651
value = undefined ! ;
1642
1652
cachedArgs = undefined ! ;
1643
1653
} ;
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
+ } ;
1644
1662
return runMemoized ;
1645
1663
1646
1664
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 ;
1655
1667
return value ;
1656
1668
}
1657
1669
cachedArgs = args ;
1658
1670
return value = callback ( ...args ) ;
1659
1671
}
1660
1672
}
1661
1673
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
+
1662
1687
/**
1663
1688
* High-order function, composes functions. Note that functions are composed inside-out;
1664
1689
* for example, `compose(a, b)` is the equivalent of `x => b(a(x))`.
0 commit comments