-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
refactor(core): add generic utilities for resolving value-or-function patterns, replace specialized resolveStaleTime
and resolveEnabled
#9212
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
resolveStaleTime
and resolveEnabled
View your CI Pipeline Execution ↗ for commit af723ec.
☁️ Nx Cloud last updated this comment at |
df0249f
to
2421a38
Compare
… patterns, replace specialized `resolveStaleTime` and `resolveEnabled` This commit introduces `isFunctionVariant()` and `resolveValueOrFunction()` utilities to replace repetitive `typeof === 'function'` checks throughout the codebase, consolidating the common "value or function that computes value" pattern.
409a222
to
b28e950
Compare
… NonFunctionGuard This simplification is possible due to the introduction of generic runtime utilities that handle value-or-function resolution. The new `resolveValueOrFunction()` utility handles the distinction between direct values and functions at runtime with proper type safety, eliminating the need for complex type-level guards.
b28e950
to
cd59cc4
Compare
9d15984
to
427c977
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I generally agree with the direction, please have a look at the comments though
@@ -58,7 +58,8 @@ | |||
"@angular/platform-browser-dynamic": "^20.0.0", | |||
"@tanstack/angular-query-experimental": "workspace:*", | |||
"eslint-plugin-jsdoc": "^50.5.0", | |||
"npm-run-all2": "^5.0.0" | |||
"npm-run-all2": "^5.0.0", | |||
"tsup": "^8.4.0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why was adding tsup
necessary here? I don’t think angular uses tsup
for bundling 🤔
): T { | ||
return isFunctionVariant(value) ? value(...args) : value | ||
} | ||
|
||
export function functionalUpdate<TInput, TOutput>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we use resolveValueOrFunction
here as well, as this also uses a typeof updater === 'function'
check ?
* const delay = resolveValueOrFunction(retryDelay, failureCount, error) | ||
* ``` | ||
*/ | ||
export function resolveValueOrFunction<T, TArgs extends Array<any>>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think a name like resolveOption
would be descriptive enough
* ``` | ||
*/ | ||
export function resolveValueOrFunction<T, TArgs extends Array<any>>( | ||
value: T | ((...args: TArgs) => T), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wondering if we should limit T
with NonFunctionGuard
like we do here:
query/packages/query-core/src/types.ts
Lines 422 to 429 in b2af568
placeholderData?: | |
| NonFunctionGuard<TQueryData> | |
| PlaceholderDataFunction< | |
NonFunctionGuard<TQueryData>, | |
TError, | |
NonFunctionGuard<TQueryData>, | |
TQueryKey | |
> |
otherwise, T
could be a function itself and then everything becomes ambiguous
hm, the failing pipeline shows a lot of type-errors |
This PR introduces
isFunctionVariant()
andresolveValueOrFunction()
utilities to replace repetitivetypeof === 'function'
checks throughout the codebase, consolidating the common "value or function that computes value" pattern.Problem and Solution
The codebase had scattered implementations of the same pattern across multiple files:
This led to code duplication, inconsistency, and maintenance overhead. We also had specialized versions like
resolveStaleTime()
andresolveEnabled()
that could be generalized.The new utilities provide a clean, generic solution:
While we could inline
typeof value === 'function'
checks, TypeScript's type narrowing doesn't work properly with generic types in complex expressions. TheisFunctionVariant()
type guard provides proper type narrowing that allowsresolveValueOrFunction()
to safely call the function variant. Without it, TypeScript throws errors because it can't guarantee the type safety across the generic boundary.Both utilities support zero-argument functions (
() => T
) and functions with parameters ((...args) => T
), making them applicable to all value-or-function patterns in the codebase.Updated implementations in
query.ts
,queryObserver.ts
, andretryer.ts
for handlinginitialData
,retryDelay
,refetchInterval
, andnotifyOnChangeProps
. These utilities can replace existingresolveStaleTime()
andresolveEnabled()
functions in future iterations.