Description
TanStack Vue Query v5 recommends using getter functions (() => value) as the idiomatic way to pass reactive parameters to useQuery, and explicitly states: "For trivial cases of simple property access, computed is an optimization with no real benefit." Vue 3.3+ introduced MaybeRefOrGetter<T> (= T | Ref<T> | (() => T)) and toValue() to standardize this pattern. However, orval's vue-query template currently wraps all parameters with MaybeRef<T> via vueWrapTypeWithMaybeRef, which only accepts T | Ref<T> and leaves out getter functions entirely.
Current behavior
Generated hook signature:
import { unref } from 'vue';
import type { MaybeRef } from 'vue';
export const getCustomerDetail = (
customerId: MaybeRef<number>, // ❌ getter () => number not accepted
...
) => {
customerId = unref(customerId); // unref() ignores getter functions
...
};
Callers who follow TanStack's recommended getter pattern get a type error and must wrap manually:
// Recommended by TanStack Vue Query docs — but orval rejects this
useGetCustomerDetail(() => props.customerId)
// Must wrap in computed instead
const idRef = computed(() => props.customerId ?? 0)
useGetCustomerDetail(idRef, { query: { enabled: computed(() => !!props.customerId) } })
Proposed behavior
import { toValue } from 'vue';
import type { MaybeRefOrGetter } from 'vue';
export const getCustomerDetail = (
customerId: MaybeRefOrGetter<number>, // ✅ accepts T | Ref<T> | (() => T)
...
) => {
customerId = toValue(customerId); // toValue() handles all three forms
...
};
Callers can use the idiomatic getter pattern directly:
useGetCustomerDetail(() => props.customerId) // ✅ no wrapper needed
Proposed solution
The change is localized to vueWrapTypeWithMaybeRef in packages/query/src/frameworks/vue.ts:
- Replace the generated type
MaybeRef<T> → MaybeRefOrGetter<T>
- Replace
import type { MaybeRef } from 'vue' → import type { MaybeRefOrGetter } from 'vue'
- Replace the call-site
unref(param) → toValue(param) for path/query params
MaybeRefOrGetter is a superset of MaybeRef, so existing call sites passing Ref or plain values continue to work without changes. An opt-in config flag (e.g. query.useMaybeRefOrGetter: true) could be added to avoid breaking existing projects.
Description
TanStack Vue Query v5 recommends using getter functions (
() => value) as the idiomatic way to pass reactive parameters touseQuery, and explicitly states: "For trivial cases of simple property access,computedis an optimization with no real benefit." Vue 3.3+ introducedMaybeRefOrGetter<T>(=T | Ref<T> | (() => T)) andtoValue()to standardize this pattern. However, orval's vue-query template currently wraps all parameters withMaybeRef<T>viavueWrapTypeWithMaybeRef, which only acceptsT | Ref<T>and leaves out getter functions entirely.Current behavior
Generated hook signature:
Callers who follow TanStack's recommended getter pattern get a type error and must wrap manually:
Proposed behavior
Callers can use the idiomatic getter pattern directly:
Proposed solution
The change is localized to
vueWrapTypeWithMaybeRefinpackages/query/src/frameworks/vue.ts:MaybeRef<T>→MaybeRefOrGetter<T>import type { MaybeRef } from 'vue'→import type { MaybeRefOrGetter } from 'vue'unref(param)→toValue(param)for path/query paramsMaybeRefOrGetteris a superset ofMaybeRef, so existing call sites passingRefor plain values continue to work without changes. An opt-in config flag (e.g.query.useMaybeRefOrGetter: true) could be added to avoid breaking existing projects.