-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
fix(vue-query): widen 'SkipToken' to 'symbol' and align 'queryOptions'/'infiniteQueryOptions' input #11427
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
base: main
Are you sure you want to change the base?
fix(vue-query): widen 'SkipToken' to 'symbol' and align 'queryOptions'/'infiniteQueryOptions' input #11427
Changes from all commits
9d20f01
682dfb5
940dd0d
01691f9
b30620b
1e4e61e
414d7cc
8d515d2
9321475
03a5f7c
fa638d3
7bc00cf
fc37daf
efb54d6
f2aae2c
b277328
101b2f2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| '@tanstack/vue-query': minor | ||
| --- | ||
|
|
||
| fix(vue-query): widen 'SkipToken' to 'symbol' and align 'queryOptions'/'infiniteQueryOptions' input | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| import { assertType, describe, expectTypeOf, it } from 'vitest' | ||
| import { computed, reactive, ref } from 'vue-demi' | ||
| import { dataTagSymbol } from '@tanstack/query-core' | ||
| import { dataTagSymbol, skipToken } from '@tanstack/query-core' | ||
| import { queryKey } from '@tanstack/query-test-utils' | ||
| import { QueryClient } from '../queryClient' | ||
| import { queryOptions } from '../queryOptions' | ||
|
|
@@ -362,4 +362,64 @@ describe('queryOptions', () => { | |
|
|
||
| expectTypeOf(options.queryKey).not.toBeUndefined() | ||
| }) | ||
|
|
||
| it('should narrow data to a defined type for a computed queryFn resolving to skipToken', () => { | ||
| const id = ref<string | null>('1') | ||
|
|
||
| const options = queryOptions({ | ||
| queryKey: computed(() => ['foo', id.value]), | ||
| queryFn: computed(() => | ||
| id.value ? () => Promise.resolve({ id: '1' }) : skipToken, | ||
| ), | ||
| }) | ||
|
|
||
| const { data } = reactive(useQuery(options)) | ||
|
|
||
| expectTypeOf(data).toEqualTypeOf<{ id: string } | undefined>() | ||
| }) | ||
|
|
||
| it('should reject a ref for an option other than enabled/queryKey/queryFn', () => { | ||
| // Unlike `useQuery`, `queryOptions` only tracks `enabled`/`queryKey`/`queryFn` reactively β every other | ||
| // option (`staleTime` here) stays a plain value. This is deliberate: the returned object is shared with | ||
| // plain APIs like `queryClient.fetchQuery`, so a `ref` slipping into an arbitrary option would make the | ||
| // declared (plain) type lie about the actual (reactive) value. | ||
| assertType( | ||
| queryOptions({ | ||
| // The directive sits on `queryKey`, not `staleTime`: overload resolution fails on the whole | ||
| // object literal and TypeScript reports it at the first property. | ||
| // @ts-expect-error staleTime must be a plain value, not a ref | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π― Functional Correctness | π Major | β‘ Quick win Place This directive applies to Proposed fix- // `@ts-expect-error` staleTime must be a plain value, not a ref
queryKey: queryKey(),
queryFn: () => Promise.resolve(5),
+ // `@ts-expect-error` staleTime must be a plain value, not a ref
staleTime: ref(1000),π€ Prompt for AI Agents |
||
| queryKey: queryKey(), | ||
| queryFn: () => Promise.resolve(5), | ||
| staleTime: ref(1000), | ||
| }), | ||
| ) | ||
| }) | ||
|
|
||
| it('should reject the whole options object wrapped in a ref', () => { | ||
| assertType( | ||
| queryOptions( | ||
| // @ts-expect-error queryOptions only accepts a plain object or a getter for the whole object, not a ref | ||
| ref({ | ||
| queryKey: queryKey(), | ||
| queryFn: () => Promise.resolve(5), | ||
| }), | ||
| ), | ||
| ) | ||
| }) | ||
|
|
||
| it('should narrow data to a defined type for a conditional skipToken inside a whole-options getter', () => { | ||
| const id = ref<string | null>('1') | ||
|
|
||
| const options = queryOptions(() => { | ||
| const current = id.value | ||
| return { | ||
| queryKey: ['foo', current], | ||
| queryFn: current ? () => Promise.resolve({ id: current }) : skipToken, | ||
| } | ||
| }) | ||
|
|
||
| const { data } = reactive(useQuery(options)) | ||
|
|
||
| expectTypeOf(data).toEqualTypeOf<{ id: string } | undefined>() | ||
| }) | ||
| }) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ποΈ Data Integrity & Integration | π Major | β‘ Quick win
π Supported by static analysis
π€ get_repo_knowledge executed:
get_repo_knowledge TanStack/query /tmp/coderabbit-repo-knowledge/tanstack-query-2191d1d3/learnings /tmp/coderabbit-repo-knowledge/tanstack-query-2191d1d3/conventionsLength of output: 4388
π Script executed:
Repository: TanStack/query
Length of output: 50372
π Script executed:
Repository: TanStack/query
Length of output: 16847
π Script executed:
Repository: TanStack/query
Length of output: 21848
π Script executed:
Repository: TanStack/query
Length of output: 17303
π Script executed:
Repository: TanStack/query
Length of output: 8660
Classify the narrowed public input type as a major change.
infiniteQueryOptions()previously accepted ref-wrapped options and refs such asstaleTimethroughUseInfiniteQueryOptions. The new overload accepts a plain output type. Existing TypeScript consumers that use those inputs will fail to compile. Change this release tomajor.Proposed changeset update
π Committable suggestion
π€ Prompt for AI Agents