Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 27 additions & 18 deletions packages/vue-query/src/__tests__/infiniteQueryOptions.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import { assertType, describe, expectTypeOf, it } from 'vitest'
import { dataTagSymbol } from '@tanstack/query-core'
import { reactive } from 'vue-demi'
import { queryKey } from '@tanstack/query-test-utils'
import { infiniteQueryOptions } from '../infiniteQueryOptions'
import { QueryClient } from '../queryClient'
import { useInfiniteQuery } from '../useInfiniteQuery'
import type { InfiniteData } from '@tanstack/query-core'

describe('infiniteQueryOptions', () => {
it('should not allow excess properties', () => {
const key = queryKey()
assertType(
infiniteQueryOptions({
queryKey: ['key'],
queryKey: key,
queryFn: () => Promise.resolve('data'),
getNextPageParam: () => 1,
initialPageParam: 1,
Expand All @@ -20,8 +22,9 @@ describe('infiniteQueryOptions', () => {
)
})
it('should infer types for callbacks', () => {
const key = queryKey()
infiniteQueryOptions({
queryKey: ['key'],
queryKey: key,
queryFn: () => Promise.resolve('data'),
staleTime: 1000,
getNextPageParam: () => 1,
Expand All @@ -32,8 +35,9 @@ describe('infiniteQueryOptions', () => {
})
})
it('should work when passed to useInfiniteQuery', () => {
const key = queryKey()
const options = infiniteQueryOptions({
queryKey: ['key'],
queryKey: key,
queryFn: () => Promise.resolve('string'),
getNextPageParam: () => 1,
initialPageParam: 1,
Expand All @@ -46,61 +50,66 @@ describe('infiniteQueryOptions', () => {
>()
})
it('should tag the queryKey with the result type of the QueryFn', () => {
const { queryKey } = infiniteQueryOptions({
queryKey: ['key'],
const key = queryKey()
const { queryKey: tagged } = infiniteQueryOptions({
queryKey: key,
queryFn: () => Promise.resolve('string'),
getNextPageParam: () => 1,
initialPageParam: 1,
})

expectTypeOf(queryKey[dataTagSymbol]).toEqualTypeOf<InfiniteData<string>>()
expectTypeOf(tagged[dataTagSymbol]).toEqualTypeOf<InfiniteData<string>>()
})
it('should tag the queryKey even if no promise is returned', () => {
const { queryKey } = infiniteQueryOptions({
queryKey: ['key'],
const key = queryKey()
const { queryKey: tagged } = infiniteQueryOptions({
queryKey: key,
queryFn: () => 'string',
getNextPageParam: () => 1,
initialPageParam: 1,
})

expectTypeOf(queryKey[dataTagSymbol]).toEqualTypeOf<InfiniteData<string>>()
expectTypeOf(tagged[dataTagSymbol]).toEqualTypeOf<InfiniteData<string>>()
})
it('should tag the queryKey with the result type of the QueryFn if select is used', () => {
const { queryKey } = infiniteQueryOptions({
queryKey: ['key'],
const key = queryKey()
const { queryKey: tagged } = infiniteQueryOptions({
queryKey: key,
queryFn: () => Promise.resolve('string'),
select: (data) => data.pages,
getNextPageParam: () => 1,
initialPageParam: 1,
})

expectTypeOf(queryKey[dataTagSymbol]).toEqualTypeOf<InfiniteData<string>>()
expectTypeOf(tagged[dataTagSymbol]).toEqualTypeOf<InfiniteData<string>>()
})
it('should return the proper type when passed to getQueryData', () => {
const { queryKey } = infiniteQueryOptions({
queryKey: ['key'],
const key = queryKey()
const { queryKey: tagged } = infiniteQueryOptions({
queryKey: key,
queryFn: () => Promise.resolve('string'),
getNextPageParam: () => 1,
initialPageParam: 1,
})

const queryClient = new QueryClient()
const data = queryClient.getQueryData(queryKey)
const data = queryClient.getQueryData(tagged)

expectTypeOf(data).toEqualTypeOf<
InfiniteData<string, unknown> | undefined
>()
})
it('should properly type when passed to setQueryData', () => {
const { queryKey } = infiniteQueryOptions({
queryKey: ['key'],
const key = queryKey()
const { queryKey: tagged } = infiniteQueryOptions({
queryKey: key,
queryFn: () => Promise.resolve('string'),
getNextPageParam: () => 1,
initialPageParam: 1,
})

const queryClient = new QueryClient()
const data = queryClient.setQueryData(queryKey, (prev) => {
const data = queryClient.setQueryData(tagged, (prev) => {
expectTypeOf(prev).toEqualTypeOf<
InfiniteData<string, unknown> | undefined
>()
Expand Down
10 changes: 7 additions & 3 deletions packages/vue-query/src/__tests__/queryClient.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { assertType, describe, expectTypeOf, it } from 'vitest'
import { queryKey } from '@tanstack/query-test-utils'
import { QueryClient } from '../queryClient'
import type { DataTag, InfiniteData } from '@tanstack/query-core'

Expand Down Expand Up @@ -113,8 +114,9 @@ describe('setQueryData', () => {

describe('fetchInfiniteQuery', () => {
it('should allow passing pages', async () => {
const key = queryKey()
const data = await new QueryClient().fetchInfiniteQuery({
queryKey: ['key'],
queryKey: key,
queryFn: () => Promise.resolve('string'),
getNextPageParam: () => 1,
initialPageParam: 1,
Expand All @@ -125,9 +127,10 @@ describe('fetchInfiniteQuery', () => {
})

it('should not allow passing getNextPageParam without pages', () => {
const key = queryKey()
assertType<Parameters<QueryClient['fetchInfiniteQuery']>>([
{
queryKey: ['key'],
queryKey: key,
queryFn: () => Promise.resolve('string'),
initialPageParam: 1,
getNextPageParam: () => 1,
Expand All @@ -136,10 +139,11 @@ describe('fetchInfiniteQuery', () => {
})

it('should not allow passing pages without getNextPageParam', () => {
const key = queryKey()
assertType<Parameters<QueryClient['fetchInfiniteQuery']>>([
// @ts-expect-error Property 'getNextPageParam' is missing
{
queryKey: ['key'],
queryKey: key,
queryFn: () => Promise.resolve('string'),
initialPageParam: 1,
pages: 5,
Expand Down
78 changes: 47 additions & 31 deletions packages/vue-query/src/__tests__/queryOptions.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
import { assertType, describe, expectTypeOf, it } from 'vitest'
import { reactive, ref } from 'vue-demi'
import { dataTagSymbol } from '@tanstack/query-core'
import { queryKey } from '@tanstack/query-test-utils'
import { QueryClient } from '../queryClient'
import { queryOptions } from '../queryOptions'
import { useQuery } from '../useQuery'

describe('queryOptions', () => {
it('should not allow excess properties', () => {
const key = queryKey()
assertType(
queryOptions({
queryKey: ['key'],
queryKey: key,
queryFn: () => Promise.resolve(5),
// @ts-expect-error this is a good error, because stallTime does not exist!
stallTime: 1000,
}),
)
})
it('should infer types for callbacks', () => {
const key = queryKey()
queryOptions({
queryKey: ['key'],
queryKey: key,
queryFn: () => Promise.resolve(5),
staleTime: 1000,
select: (data) => {
Expand All @@ -27,84 +30,92 @@ describe('queryOptions', () => {
})
})
it('should work when passed to useQuery', () => {
const key = queryKey()
const options = queryOptions({
queryKey: ['key'],
queryKey: key,
queryFn: () => Promise.resolve(5),
})

const { data } = reactive(useQuery(options))
expectTypeOf(data).toEqualTypeOf<number | undefined>()
})
it('should tag the queryKey with the result type of the QueryFn', () => {
const { queryKey } = queryOptions({
queryKey: ['key'],
const key = queryKey()
const { queryKey: tagged } = queryOptions({
queryKey: key,
queryFn: () => Promise.resolve(5),
})

expectTypeOf(queryKey[dataTagSymbol]).toEqualTypeOf<number>()
expectTypeOf(tagged[dataTagSymbol]).toEqualTypeOf<number>()
})
it('should tag the queryKey even if no promise is returned', () => {
const { queryKey } = queryOptions({
queryKey: ['key'],
const key = queryKey()
const { queryKey: tagged } = queryOptions({
queryKey: key,
queryFn: () => 5,
})

expectTypeOf(queryKey[dataTagSymbol]).toEqualTypeOf<number>()
expectTypeOf(tagged[dataTagSymbol]).toEqualTypeOf<number>()
})
it('should tag the queryKey with unknown if there is no queryFn', () => {
const { queryKey } = queryOptions({
queryKey: ['key'],
const key = queryKey()
const { queryKey: tagged } = queryOptions({
queryKey: key,
})

expectTypeOf(queryKey[dataTagSymbol]).toEqualTypeOf<unknown>()
expectTypeOf(tagged[dataTagSymbol]).toEqualTypeOf<unknown>()
})
it('should tag the queryKey with the result type of the QueryFn if select is used', () => {
const { queryKey } = queryOptions({
queryKey: ['key'],
const key = queryKey()
const { queryKey: tagged } = queryOptions({
queryKey: key,
queryFn: () => Promise.resolve(5),
select: (data) => data.toString(),
})

expectTypeOf(queryKey[dataTagSymbol]).toEqualTypeOf<number>()
expectTypeOf(tagged[dataTagSymbol]).toEqualTypeOf<number>()
})
it('should return the proper type when passed to getQueryData', () => {
const { queryKey } = queryOptions({
queryKey: ['key'],
const key = queryKey()
const { queryKey: tagged } = queryOptions({
queryKey: key,
queryFn: () => Promise.resolve(5),
})

const queryClient = new QueryClient()
const data = queryClient.getQueryData(queryKey)
const data = queryClient.getQueryData(tagged)

expectTypeOf(data).toEqualTypeOf<number | undefined>()
})
it('should properly type updaterFn when passed to setQueryData', () => {
const { queryKey } = queryOptions({
queryKey: ['key'],
const key = queryKey()
const { queryKey: tagged } = queryOptions({
queryKey: key,
queryFn: () => Promise.resolve(5),
})

const queryClient = new QueryClient()
const data = queryClient.setQueryData(queryKey, (prev) => {
const data = queryClient.setQueryData(tagged, (prev) => {
expectTypeOf(prev).toEqualTypeOf<number | undefined>()
return prev
})
expectTypeOf(data).toEqualTypeOf<number | undefined>()
})
it('should properly type value when passed to setQueryData', () => {
const { queryKey } = queryOptions({
queryKey: ['key'],
const key = queryKey()
const { queryKey: tagged } = queryOptions({
queryKey: key,
queryFn: () => Promise.resolve(5),
})

const queryClient = new QueryClient()

// @ts-expect-error value should be a number
queryClient.setQueryData(queryKey, '5')
queryClient.setQueryData(tagged, '5')
// @ts-expect-error value should be a number
queryClient.setQueryData(queryKey, () => '5')
queryClient.setQueryData(tagged, () => '5')

const data = queryClient.setQueryData(queryKey, 5)
const data = queryClient.setQueryData(tagged, 5)

expectTypeOf(data).toEqualTypeOf<number | undefined>()
})
Expand All @@ -126,10 +137,11 @@ describe('queryOptions', () => {
})

it('TData should always be defined when initialData is provided as a function which ALWAYS returns the data', () => {
const key = queryKey()
const { data } = reactive(
useQuery(
queryOptions({
queryKey: ['key'],
queryKey: key,
queryFn: () => {
return {
wow: true,
Expand All @@ -146,10 +158,11 @@ describe('queryOptions', () => {
})

it('TData should have undefined in the union when initialData is NOT provided', () => {
const key = queryKey()
const { data } = reactive(
useQuery(
queryOptions({
queryKey: ['key'],
queryKey: key,
queryFn: () => {
return {
wow: true,
Expand All @@ -163,10 +176,11 @@ describe('queryOptions', () => {
})

it('TData should have undefined in the union when initialData is provided as a function which can return undefined', () => {
const key = queryKey()
const { data } = reactive(
useQuery(
queryOptions({
queryKey: ['key'],
queryKey: key,
queryFn: () => {
return {
wow: true,
Expand All @@ -181,10 +195,11 @@ describe('queryOptions', () => {
})

it('TData should be narrowed after an isSuccess check when initialData is provided as a function which can return undefined', () => {
const key = queryKey()
const { data, isSuccess } = reactive(
useQuery(
queryOptions({
queryKey: ['key'],
queryKey: key,
queryFn: () => {
return {
wow: true,
Expand All @@ -201,10 +216,11 @@ describe('queryOptions', () => {
})

it('data should not have undefined when initialData is provided', () => {
const key = queryKey()
const { data } = reactive(
useQuery(
queryOptions({
queryKey: ['query-key'],
queryKey: key,
initialData: 42,
}),
),
Expand Down
Loading
Loading