Skip to content

[vue-query] Type error returning undefined from initialData in queryOptions #9069

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

Open
romansp opened this issue Apr 25, 2025 · 8 comments · Fixed by #9077 · May be fixed by #9088
Open

[vue-query] Type error returning undefined from initialData in queryOptions #9069

romansp opened this issue Apr 25, 2025 · 8 comments · Fixed by #9077 · May be fixed by #9088

Comments

@romansp
Copy link

romansp commented Apr 25, 2025

Describe the bug

In vue-query if initialData function returns undefined typescript error is displayed.

According to the docs this should be allowed https://tanstack.com/query/latest/docs/framework/react/guides/initial-query-data#conditional-initial-data-from-cache and query should fetch from hard loading state instead.

Your minimal, reproducible example

https://www.typescriptlang.org/play/?#code/JYWwDg9gTgLgBAbzgRwK4FMoE8DyYbAQB2AznAL5wBmUEIcARAAIwCGpbAxgNYD0AbhgC0aTFgYBuAFBTgRGJiqtO6OAGFiVYAHNEUuHH6sANhgBccEjChzt08jKqoinAsTjb0MDUS3aAFACUegZQXqhQRHAACrQgwCToAHRhJBDG-Oj+SEam6BYA5AAW6MbGEAUUcKxkPn6B9jIAJuicxqxhHuUARiYhcHIKUEoqcACSRMAEJgAirGz9BpyaOgD8FnU60gYO+oYdcAD6h3JTwLPzrBYTZxdsjVLLHHAQ+ISkcAC8KBjYeG6kbJ7UTYADS6CwFgA2gwnn4GABdapkJ5WAA0wN+WAAYkQLJ5vCttBiDKdpsY5mwLEEvgA+RZwMIwCJRbQ9EwAFSKCSSxzJ5wplyScK2e3IGPIDSAA

Steps to reproduce

  1. Go to minimal repro typescript playground
  2. See type error for initialData
No overload matches this call.
  Overload 1 of 2, '(options: UndefinedInitialQueryOptions<Config, Error, Config, readonly ["config"]>): UndefinedInitialQueryOptions<Config, Error, Config, readonly [...]> & { ...; }', gave the following error.
    Type '() => Config | undefined' is not assignable to type 'undefined'.
  Overload 2 of 2, '(options: DefinedInitialQueryOptions<Config, Error, Config, readonly ["config"]>): DefinedInitialQueryOptions<Config, Error, Config, readonly [...]> & { ...; }', gave the following error.
    Type '() => Config | undefined' is not assignable to type 'Config | (() => Config) | (MaybeRefDeep<Config | InitialDataFunction<Config> | undefined> & (Config | (() => Config)))'.
      Type '() => Config | undefined' is not assignable to type '() => Config'.
        Type 'Config | undefined' is not assignable to type 'Config'.
          Type 'undefined' is not assignable to type 'Config'.(2769)
hydration-BlEK5ylC.d.ts(606, 5): The expected type comes from property 'initialData' which is declared here on type 'UndefinedInitialQueryOptions<Config, Error, Config, readonly ["config"]>'
hydration-BlEK5ylC.d.ts(606, 5): The expected type comes from property 'initialData' which is declared here on type 'DefinedInitialQueryOptions<Config, Error, Config, readonly ["config"]>'

Expected behavior

initialData allows to return undefined. No type errors produced.

How often does this bug happen?

Every time

Screenshots or Videos

No response

Platform

N/A

Tanstack Query adapter

vue-query

TanStack Query version

v5.74.6

TypeScript version

v5.8.3

Additional context

Query still fetches just fine from hard loading state so the logic is correct. Also no type errors in react-query for the exact same code.

@saul-atomrigs
Copy link
Contributor

Currently the implementation is:

export type UndefinedInitialQueryOptions<
  TQueryFnData = unknown,
  TError = DefaultError,
  TData = TQueryFnData,
  TQueryKey extends QueryKey = QueryKey,
> = UseQueryOptions<TQueryFnData, TError, TData, TQueryFnData, TQueryKey> & {
  initialData?: undefined
}

so in your example if you set initialData: undefined the type error goes away
I think the docs should change the wording

@romansp
Copy link
Author

romansp commented Apr 26, 2025

@saul-atomrigs Yeah but initialData: undefined won't be the same?

Same exact code in react-query doesn't produce any errors.

@saul-atomrigs
Copy link
Contributor

I think the equivalent type in react-query is the following, which has a few more things:

export type UndefinedInitialDataOptions<
  TQueryFnData = unknown,
  TError = DefaultError,
  TData = TQueryFnData,
  TQueryKey extends QueryKey = QueryKey,
> = UseQueryOptions<TQueryFnData, TError, TData, TQueryKey> & {
  initialData?:
    | undefined
    | InitialDataFunction<NonUndefinedGuard<TQueryFnData>> // *** this
    | NonUndefinedGuard<TQueryFnData> // *** and this
}

Should vue-query add these lines?

@TkDodo
Copy link
Collaborator

TkDodo commented Apr 26, 2025

Should vue-query add these lines?

yeah probably. initialData function should be able to return undefined

@romansp
Copy link
Author

romansp commented Apr 27, 2025

Thank you @saul-atomrigs for the quick fix.

Closing as completed by #9073.

@romansp romansp closed this as completed Apr 27, 2025
@romansp
Copy link
Author

romansp commented Apr 28, 2025

Will have to reopen. Just tried upgrading in our codebase and I'm afraid #9073 caused type regression for the case when initialData is set to an object and used with useQuery.

Minimal repro: https://www.typescriptlang.org/play/?#code/JYWwDg9gTgLgBAbzgRwK4FMoE8DyYbAQB2AzgDRyonoCKG2cAvnAGZQQhwBEAAjAIakBAYwDWAegBuGALRpMWLgG4AUCuBEYmFv2Ho4AYWItgAc0Qq4cABboANnYgAuOCRhQNp1YzUtURYQJiOFN0GCMiE1MACgBKCysoMNQoIjgABXYQYGoAOiSSCDtJdGikWwdnOAByCsdqpjh+EkNjM1jvNWFiNzgIfEJSOABeFHpcAZ6yyzGFAGl0LBcAbS5uyLMuAF0mlvW3Mhn5bAAxIhdQ8LbTQ6sNYAJ+OwARfgEXBBmrOqra+3qZj5GB0uj14EgACZvfiNUZUWjjaL9IKkEEqfbwSRPDAjOBQgS5LF2DCqCEQADKHDC1k8AHUHtYAGrY0pEjC5H4gqzcnm8vlwcTiOAAPQA-L5-IFBniKVSYDSiKZ6fLmcTWSyXG4PIr4p8rPsiuhco4Ymz0CDGEA

data.value should have been narrowed to just string and not string | undefined. In react-query it's narrowed correctly, but there you don't have Ref<T> for data.

I'm worried this may be Vue's limitation.

@saul-atomrigs
Copy link
Contributor

@TkDodo @DamianOsipiuk
I'd like to suggest rolling back the previous changes (including the tests) and instead adding (() => undefined):

export type UndefinedInitialQueryOptions<
  TQueryFnData = unknown,
  TError = DefaultError,
  TData = TQueryFnData,
  TQueryKey extends QueryKey = QueryKey,
> = UseQueryOptions<TQueryFnData, TError, TData, TQueryFnData, TQueryKey> & {
  initialData?: undefined 
     | (() => undefined)  // add this
  // | InitialDataFunction<NonUndefinedGuard<TQueryFnData>>
  // | NonUndefinedGuard<TQueryFnData>
}

Let me know if there's a better approach

@romansp
Copy link
Author

romansp commented Apr 29, 2025

I'm sorry but the original issue is now back. Can we please reopen @DamianOsipiuk?

Using the following type test case from react-query produces type error check for initialData.
https://www.typescriptlang.org/play/?#code/JYWwDg9gTgLgBAbzgRwK4FMoE8DyYbAQB2AznAL5wBmUEIcARAAIwCGpbAxgNYD0AbhgC0aTFgYBuAFBS4nYiXgR8hUnAC8cABTAAJgC44iqMCIBzOAB84RVABs7ASg0A+WSgzY8BBVoTu4DzEAaXQsQwBtAHIYCF0IKIAaOD0AXUSAoOwAMSJDLWd1N0CSuAAFWhBgEnQAOih0Egg7fnQ-TNK9QyiARiSOkoIYO3RugBEIOAAZVlQiXWx+0sDyRwzOomACVjsx1jZ8wuLlgEI9AcCAfjg53XQqU3RdC7hDf2WPlN11z9Khke6AElNts7HA9mwlr8KD9VkA

I think I know what's going on and how to fix that properly for both useQuery and queryOptions. I'm going to provide a PR.

romansp added a commit to romansp/query that referenced this issue Apr 29, 2025
…ver type safety of initialData in "queryOptions-to-useQuery" interaction
romansp added a commit to romansp/query that referenced this issue Apr 29, 2025
… useQuery to come before general ones (TanStack#9069)

This instructs TypeScript to pick correct function overload when initialData is defined.
romansp added a commit to romansp/query that referenced this issue Apr 29, 2025
… useQuery to come before general ones (TanStack#9069)

This instructs TypeScript to pick correct function overload when initialData is defined.
@DamianOsipiuk DamianOsipiuk reopened this Apr 29, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants