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
initial-roseOP•15mo ago
I should also mention this is only a typing issue, if I ts-ignore the lines it all works
xenogeneic-maroon•15mo ago
Huh, is it only when you spread into query keys?
For some reason this isn't matching the first overload of setQueryData
initial-roseOP•15mo 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
conscious-sapphire•15mo 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 TSinitial-roseOP•15mo ago
1.
current.prices
is actually a Map<string, Decimal>
2. KEY_CURRENT_MARKET
is inferred, simply defined as const KEY_CURRENT_MARKET = ["currentValues"];
conscious-sapphire•15mo ago
@SmilyContainer Show me please
1.
StockHoldingsApi.getCurrent
implementation
2. prices
initial-roseOP•15mo 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 😀
conscious-sapphire•15mo ago
@SmilyContainer Did you update
tanstack/query
types when migrating to v5?initial-roseOP•15mo ago
are they separate packages? I've always just had the one package:
conscious-sapphire•15mo ago
I'm trying to break it with different approaches, but I have no succeeded yet 🙂
conscious-sapphire•15mo ago

conscious-sapphire•15mo ago
F* yeah! I found it.
conscious-sapphire•15mo ago
@SmilyContainer You need to add curly braces in your
forEach
fn and the error will go away.
conscious-sapphire•15mo ago
😀
initial-roseOP•15mo ago
wow! that's subtle, i'll confirm in a few after undoing my workaround
conscious-sapphire•15mo 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.initial-roseOP•15mo 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
conscious-sapphire•15mo ago
no problem 🙂
initial-roseOP•15mo ago
just sat back down, reverted the workaround, added the curly braces to the 3 instances of the error, all fixed
conscious-sapphire•15mo 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 errorinitial-roseOP•15mo 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"?
conscious-sapphire•15mo 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
initial-roseOP•15mo 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