-
-
Notifications
You must be signed in to change notification settings - Fork 3k
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
better type narrowing for initialData #3310
Comments
So whenever |
@kettanaito yes, that is correct. cached data is never removed and initialData synchronously populates the cache. Even if you programmatically remove the query and re-render, it will be recreated with initialData. Even if the query errors, the data is still kept. I see no scenario where data can be undefined if initialData is provided :) |
Correction: |
You can still pass a function to |
@henribru yes, but I don' see a difference between:
and
as the signature for
so, yes, to be absolutely correct: As long as I think we would need to look at the type of |
@TkDodo I'd like to work on this issue |
To my knowledge using an overload-based approach is not possible with typescript at the moment (see this playground). A return type of a function can not be inferred based on whether a certain object property is set or not. This can only be solved by introducing a generic for the query options and using conditional types based on that generic for the function return type. But maybe some typescript guru can prove me wrong :) |
@TkDodo Update here, I was trying to do it via conditional types with generic but that wasn't working as expected. So I have asked a question for it on StackOverflow. And as mentioned by @yss14 even the overload based approach also doesn't seem to be working as expected. Do you have any other ideas on what else we can try out here? |
@prateek3255 I answered your SO question :) Here is my working playground for the |
Thanks @yss14. Will check it out 🙌 |
|
Question not relate or related? (i just started using react-query so i am not well know about how it works, was searching issues and this was the closest related to my problem 😄 ) |
Doesn't work. You can always say |
So I tried using the solution by @yss14 but the type narrowing still doesn't seem to be working as expected when I try using it with the basic-typescript example. Also I get a few type errors due to the return I have also updated the basic-typescript a little bit to test the changes. Opened a draft PR with #3557 |
I tinkered a little bit more and was able to fix the type errors and get one of the overloads working that @yss14 demonstrated with the playground, have pushed the updated code in the same PR, but now the problem is that one of a few other overloads are not working at all, and breaking the existing types. For instance the Although there are some other type errors within, the tests as well with this approach, but we'll be able to figure them out, once we figure out what's causing this issue. @TkDodo @yss14 Do you have any idea on what's wrong with the above playground? |
Likely a naive attempt here: |
when providing
initialData
directly on aquery
, the type ofdata
is guaranteed to beTData
, notTData | undefined
:TypeScript playground
ideally, we could narrow the type when
initialData
is provided. This only works forinitialData
becauseinitialData
is executed in the constructor of the query, and because it is synchronous. Also, it can only work onv4
because inv3
,undefined
is technically still valid for theTData
generic, so we cannot remove it from the union. Inv4
,undefined
is illegal for successful queries, so that would now work.Keep in mind that
initialData
can also be a function that returnsTData | undefined
, so this should also narrow if the function returnsTData
.It does NOT work for:
placeholderData
, because that will revert back toundefined
when a query errorsinitialData
being provided globally, because TS cannot know that on an instance level. It needs to be explicitly passed touseQuery
.suspense
or any other case because a query can becancelled
while it is initiallyfetching
, in which case it will bereset
to its initial state.queryClient.resetQueries
also does that. Also, without network connection in the default network mode, the query will be infetchStatus: 'paused'
and will also not have data.I guess we could potentially do this with another overload that has
initialData
provided and removesundefined
from the result union, but we would also have do this foruseQueries
.I would like to avoid having to add another generic to
useQuery
, as we already have four of them.Because this is for v4, PRs should go to the
beta
branch please.The text was updated successfully, but these errors were encountered: