-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Description
when providing initialData directly on a query, the type of data is guaranteed to be TData, not TData | undefined:
const { data } = useQuery(['test'], () => Promise.resolve('test'), { initialData: 'something' })
// 🚨 Object is possibly 'undefined'.(2532)
data.toUpperCase()
ideally, we could narrow the type when initialData is provided. This only works for initialData because initialData is executed in the constructor of the query, and because it is synchronous. Also, it can only work on v4 because in v3, undefined is technically still valid for the TData generic, so we cannot remove it from the union. In v4, undefined is illegal for successful queries, so that would now work.
Keep in mind that initialData can also be a function that returns TData | undefined, so this should also narrow if the function returns TData.
It does NOT work for:
placeholderData, because that will revert back toundefinedwhen a query errorsinitialDatabeing provided globally, because TS cannot know that on an instance level. It needs to be explicitly passed touseQuery.suspenseor any other case because a query can becancelledwhile it is initiallyfetching, in which case it will beresetto its initial state.queryClient.resetQueriesalso 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 removes undefined from the result union, but we would also have do this for useQueries.
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.