setQueryData changes in v5?
I'm upgrading my project from v4 to v5 of react query today and have just a couple typescript errors with some calls to setQueryData:
and
I have dozens of other calls to setQueryData that don't have any error
here's an example where
p is the Decimal type we're getting an error from:
Thanks in advance for any insight.23 Replies
fair-roseOP•2y ago
I should also mention this is only a typing issue, if I ts-ignore the lines it all works
mute-gold•2y ago
Huh, is it only when you spread into query keys?
For some reason this isn't matching the first overload of setQueryData
fair-roseOP•2y ago
nope, I have examples spreading and it working
so everywhere in my project that currently works both functionally and type-wise, the signature on
setQueryData has updater: unknown, whereas the problem areas, pycharm reports the type as Updater<void | undefined, void | undefined>, not entirely sure why at the moment
as an experiment, I tried a refactor and was able to appease the wonderful typing gods, though I'm not quite sure why
absent-sapphire•2y ago
2 issues bother me
1.
current.prices.forEach((p, symbol) => symbol is of type number, not a string
2. If KEY_CURRENT_MARKET is a read-only array it's probably inferred literally. When you spread it, it probably goes to smth more general like a string[]
Of course, it's hard to tell what causes the issue without looking at the code and how everything is structured. Small details matter in TSfair-roseOP•2y ago
1.
current.prices is actually a Map<string, Decimal>
2. KEY_CURRENT_MARKET is inferred, simply defined as const KEY_CURRENT_MARKET = ["currentValues"];absent-sapphire•2y ago
@SmilyContainer Show me please
1.
StockHoldingsApi.getCurrent implementation
2. pricesfair-roseOP•2y ago
interface definitions too
thanks for looking and let me know if anything is silly, it's a solo closed source project and I'm more of a backend/infra person so I don't get any feedback on my weird react/ts 😀
absent-sapphire•2y ago
@SmilyContainer Did you update
tanstack/query types when migrating to v5?fair-roseOP•2y ago
are they separate packages? I've always just had the one package:
absent-sapphire•2y ago
I'm trying to break it with different approaches, but I have no succeeded yet 🙂
absent-sapphire•2y ago

absent-sapphire•2y ago
F* yeah! I found it.
absent-sapphire•2y ago
@SmilyContainer You need to add curly braces in your
forEach fn and the error will go away.
absent-sapphire•2y ago
😀
fair-roseOP•2y ago
wow! that's subtle, i'll confirm in a few after undoing my workaround
absent-sapphire•2y ago
ForEach callback returns
void so when you do not wrap it inside the curly braces you return a qc.setQueryData return type. Those 2 combine and break somewhere along the line. Unfortunately, that's the most info I can provide. Query has sophisticated types and it's hard to track down what happens under the hood.fair-roseOP•2y ago
yea, i took a look at Tk's PR that changed the types on this function in v5 and it's a complicated little PR from a typing perspective. I really appreciate the insight and especially the explanation
absent-sapphire•2y ago
no problem 🙂
fair-roseOP•2y ago
just sat back down, reverted the workaround, added the curly braces to the 3 instances of the error, all fixed
absent-sapphire•2y ago
I'm glad we found the cause of the problem. I assume it works like this.
1. Ts knows that the return of the
forEach callback is always void
2. Since you didn't provide any Types to setQueryData and you returned it from the callback, TS assigns void to return type of setQueryData
3. Then it backfires going back from the return type all the way up the setQueryData types trying to infer what types of arguments can satisfy the return type void
4. That's how you got this errorfair-roseOP•2y ago
really interesting, should i open up an issue on github for this or is this a lesson for me that "you shouldn't let forEach unnecessarily return something"?
absent-sapphire•2y ago
It's not necessary problem with types, it's a normal ts behavior when it tries to infer types based on the info it has. It's just not obvious because error makes you think that something wrong with the argument, when in reality problem lies in the return type.
It's better just keep in mind that you should not return anything from the foreach cb
fair-roseOP•2y ago
great context for me, I really appreciate the insights, i'll have to remember that and maybe just use for loops more often to avoid the issue