Complex types with select & placeholderData #8552
Replies: 1 comment 1 reply
-
If you use All your type workarounds are just that - workarounds. Passing type parameters specifically to So what I would do is make |
Beta Was this translation helpful? Give feedback.
-
Background
Recently, I came across some code that looked like this:
The Goal
I realized I could simplify by replacing
useMemo
with aselect
and theuseEffect
withenabled: someCondition
:Problem 1: Null-Pointer Exception
The types work out fine and everything compiles and runs. But there's a new bug. The
select
doesn't run on the empty initial data, soquery.data
isundefined
, not[]
. I get a null-pointer exception onquery.data.join
.I figure I can solve this "the TanStack Query way" by introducing
placeholderData
:Problem 2: Type Errors
But this causes a type error:
The type of
placeholderData
needs to be the same as the type ofqueryFn
, but I don't want to have to fill in the rest of theQueryResult
structure because it's huge and messy. So I try narrowing the type at theuseQuery
level:But this introduces a new type error:
By default,
TQueryFnData
isunknown
, soTData
is alsounknown
, causing TypeScript to intuit it. But now that I've explicitly defined the type forqueryFn
andplaceholderData
, TypeScript is trying to use that type for the result ofselect
.Solutions
The first is to explicitly define both
TQueryFnData
andTData
:It's OK. I'd take it if it were the only option, but there's a lot of explicit type coupling that will make it hard to modify.
The second is to explicitly type
TQueryFnData
and explicitly not defineTData
:That works because I'm forcing TypeScript to intuit
TData
. I like this about the same as the first option. It feels like I'm copying some semi-private aspects of the TanStack Query API into my code.The third option is to put the type refinement on
queryFn
and not onuseQuery
:Of the three options I found, I like this best. It seems the least likely to break due to changes in TanStack Query because I'm following the intent of the API.
Future Work
It looks like TanStack Query uses
TQueryFnData
as the argument forselect
. It would be lovely if it could further refine that asTQueryFnData & PlaceholderData
so I'm guaranteed thatselect
can run on both placeholder and real data without having to stub out the full type.Beta Was this translation helpful? Give feedback.
All reactions