Skip to content

fix(react-query): update Incorrect Inference of GetDefinedOrUndefinedQueryResult when TData is assignable to CallableFunction #9278

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
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
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
96 changes: 83 additions & 13 deletions packages/react-query/src/__tests__/useQueries.test-d.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,23 +41,93 @@ describe('UseQueries config object overload', () => {
expectTypeOf(query3Data).toEqualTypeOf<string | undefined>()
})

it('TData should be defined when passed through queryOptions', () => {
const options = queryOptions({
queryKey: ['key'],
queryFn: () => {
return {
describe('TData should be correctly inferred when using queryOptions', () => {
it('TData should be defined when passed through queryOptions', () => {
const options = queryOptions({
queryKey: ['key'],
queryFn: () => {
return {
wow: true,
}
},
initialData: {
wow: true,
}
},
initialData: {
wow: true,
},
},
})
const queryResults = useQueries({ queries: [options] })

const data = queryResults[0].data

expectTypeOf(data).toEqualTypeOf<{ wow: boolean }>()
})
const queryResults = useQueries({ queries: [options] })

const data = queryResults[0].data
it('TData should be undefined when initialData is not provided', () => {
const options = queryOptions({
queryKey: ['key'],
queryFn: () => {
return {
wow: true,
}
},
})

expectTypeOf(data).toEqualTypeOf<{ wow: boolean }>()
const queryResults = useQueries({ queries: [options] })

const data = queryResults[0].data

expectTypeOf(data).toEqualTypeOf<{ wow: boolean } | undefined>()
})

it('TData should be undefined when initialData is not provided, and TQueryFnData extends a base javascript object', () => {
// Create a union of objects, which each have a single key (and corresponding value type) from CallableFunction,
// this better mimics the behaviour of returning an object which has a single key that matches any of the known keys
// that exist on an CallableFunction in javascript (i.e { name: string })
type Data = {
[K in keyof CallableFunction]: {
[key in K]: CallableFunction[key]
}
}[keyof CallableFunction]

// Object with individual key from CallableFunction
const queryOptions1 = queryOptions({
queryKey: ['key1'],
queryFn: (): Promise<Data> => {
return {
name: 'example',
}
},
})

// Object with an actual CallableFunction
const queryOptions2 = queryOptions({
queryKey: ['key2'],
queryFn: (): Promise<CallableFunction> => {
return () => void 0
},
})

// Object with matching key from CallableFunction, but different value type
const queryOptions3 = queryOptions({
queryKey: ['key3'],
queryFn: (): Promise<{ name: number }> => {
return {
name: 42,
}
},
})

const queryResults1 = useQueries({ queries: [queryOptions1] })
const queryResults2 = useQueries({ queries: [queryOptions2] })
const queryResults3 = useQueries({ queries: [queryOptions3] })

const data1 = queryResults1[0].data
const data2 = queryResults2[0].data
const data3 = queryResults3[0].data

expectTypeOf(data1).toEqualTypeOf<Data | undefined>()
expectTypeOf(data2).toEqualTypeOf<CallableFunction | undefined>()
expectTypeOf(data3).toEqualTypeOf<{ name: number } | undefined>()
})
})

it('should be possible to define a different TData than TQueryFnData using select with queryOptions spread into useQuery', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/react-query/src/useQueries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ type GetUseQueryOptionsForUseQueries<T> =

// A defined initialData setting should return a DefinedUseQueryResult rather than UseQueryResult
type GetDefinedOrUndefinedQueryResult<T, TData, TError = unknown> = T extends {
initialData?: infer TInitialData
initialData: infer TInitialData
}
? unknown extends TInitialData
? UseQueryResult<TData, TError>
Expand Down
Loading