Skip to content

Commit

Permalink
Merge pull request #4147 from reduxjs/more-typed-wrappers
Browse files Browse the repository at this point in the history
Create more Typed wrappers for RTKQ hook types
  • Loading branch information
EskiMojo14 committed Feb 11, 2024
2 parents 242a016 + 02fa764 commit 1cb709b
Show file tree
Hide file tree
Showing 4 changed files with 181 additions and 1 deletion.
62 changes: 62 additions & 0 deletions packages/toolkit/src/query/react/buildHooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ export type UseQuery<D extends QueryDefinition<any, any, any, any>> = <
options?: UseQuerySubscriptionOptions & UseQueryStateOptions<D, R>,
) => UseQueryHookResult<D, R>

export type TypedUseQuery<
ResultType,
QueryArg,
BaseQuery extends BaseQueryFn,
> = UseQuery<QueryDefinition<QueryArg, BaseQuery, string, ResultType, string>>

export type UseQueryHookResult<
D extends QueryDefinition<any, any, any, any>,
R = UseQueryStateDefaultResult<D>,
Expand Down Expand Up @@ -182,6 +188,14 @@ export type UseQuerySubscription<
options?: UseQuerySubscriptionOptions,
) => UseQuerySubscriptionResult<D>

export type TypedUseQuerySubscription<
ResultType,
QueryArg,
BaseQuery extends BaseQueryFn,
> = UseQuerySubscription<
QueryDefinition<QueryArg, BaseQuery, string, ResultType, string>
>

export type UseQuerySubscriptionResult<
D extends QueryDefinition<any, any, any, any>,
> = Pick<QueryActionCreatorResult<D>, 'refetch'>
Expand Down Expand Up @@ -231,6 +245,14 @@ export type UseLazyQuery<D extends QueryDefinition<any, any, any, any>> = <
UseLazyQueryLastPromiseInfo<D>,
]

export type TypedUseLazyQuery<
ResultType,
QueryArg,
BaseQuery extends BaseQueryFn,
> = UseLazyQuery<
QueryDefinition<QueryArg, BaseQuery, string, ResultType, string>
>

export type LazyQueryTrigger<D extends QueryDefinition<any, any, any, any>> = {
/**
* Triggers a lazy query.
Expand Down Expand Up @@ -258,6 +280,14 @@ export type LazyQueryTrigger<D extends QueryDefinition<any, any, any, any>> = {
): QueryActionCreatorResult<D>
}

export type TypedLazyQueryTrigger<
ResultType,
QueryArg,
BaseQuery extends BaseQueryFn,
> = LazyQueryTrigger<
QueryDefinition<QueryArg, BaseQuery, string, ResultType, string>
>

/**
* A React hook similar to [`useQuerySubscription`](#usequerysubscription), but with manual control over when the data fetching occurs.
*
Expand All @@ -275,6 +305,14 @@ export type UseLazyQuerySubscription<
options?: SubscriptionOptions,
) => readonly [LazyQueryTrigger<D>, QueryArgFrom<D> | UninitializedValue]

export type TypedUseLazyQuerySubscription<
ResultType,
QueryArg,
BaseQuery extends BaseQueryFn,
> = UseLazyQuerySubscription<
QueryDefinition<QueryArg, BaseQuery, string, ResultType, string>
>

export type QueryStateSelector<
R extends Record<string, any>,
D extends QueryDefinition<any, any, any, any>,
Expand All @@ -297,6 +335,14 @@ export type UseQueryState<D extends QueryDefinition<any, any, any, any>> = <
options?: UseQueryStateOptions<D, R>,
) => UseQueryStateResult<D, R>

export type TypedUseQueryState<
ResultType,
QueryArg,
BaseQuery extends BaseQueryFn,
> = UseQueryState<
QueryDefinition<QueryArg, BaseQuery, string, ResultType, string>
>

export type UseQueryStateOptions<
D extends QueryDefinition<any, any, any, any>,
R extends Record<string, any>,
Expand Down Expand Up @@ -514,6 +560,14 @@ export type UseMutation<D extends MutationDefinition<any, any, any, any>> = <
options?: UseMutationStateOptions<D, R>,
) => readonly [MutationTrigger<D>, UseMutationStateResult<D, R>]

export type TypedUseMutation<
ResultType,
QueryArg,
BaseQuery extends BaseQueryFn,
> = UseMutation<
MutationDefinition<QueryArg, BaseQuery, string, ResultType, string>
>

export type MutationTrigger<D extends MutationDefinition<any, any, any, any>> =
{
/**
Expand All @@ -535,6 +589,14 @@ export type MutationTrigger<D extends MutationDefinition<any, any, any, any>> =
(arg: QueryArgFrom<D>): MutationActionCreatorResult<D>
}

export type TypedUseMutationTrigger<
ResultType,
QueryArg,
BaseQuery extends BaseQueryFn,
> = MutationTrigger<
MutationDefinition<QueryArg, BaseQuery, string, ResultType, string>
>

/**
* Wrapper around `defaultQueryStateSelector` to be used in `useQuery`.
* We want the initial render to already come back with
Expand Down
8 changes: 8 additions & 0 deletions packages/toolkit/src/query/react/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,13 @@ export type {
TypedUseQueryHookResult,
TypedUseQueryStateResult,
TypedUseQuerySubscriptionResult,
TypedLazyQueryTrigger,
TypedUseLazyQuery,
TypedUseMutation,
TypedUseMutationTrigger,
TypedUseQueryState,
TypedUseQuery,
TypedUseQuerySubscription,
TypedUseLazyQuerySubscription,
} from './buildHooks'
export { createApi, reactHooksModule, reactHooksModuleName }
2 changes: 1 addition & 1 deletion packages/toolkit/src/query/tests/buildHooks.test-d.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ describe('type tests', () => {
}
})

test('selectFromResult (query) behaviors', () => {
test('top level named hooks', () => {
interface Post {
id: number
name: string
Expand Down
110 changes: 110 additions & 0 deletions packages/toolkit/src/query/tests/unionTypes.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,16 @@ import type {
FetchBaseQueryError,
TypedUseMutationResult,
TypedUseQueryHookResult,
TypedUseQueryState,
TypedUseQueryStateResult,
TypedUseQuerySubscriptionResult,
TypedLazyQueryTrigger,
TypedUseLazyQuery,
TypedUseLazyQuerySubscription,
TypedUseMutation,
TypedUseMutationTrigger,
TypedUseQuerySubscription,
TypedUseQuery,
} from '@reduxjs/toolkit/query/react'
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'

Expand Down Expand Up @@ -725,6 +733,10 @@ describe('union types', () => {

describe('"Typed" helper types', () => {
test('useQuery', () => {
expectTypeOf<TypedUseQuery<string, void, typeof baseQuery>>().toMatchTypeOf(
api.endpoints.getTest.useQuery,
)

const result = api.endpoints.getTest.useQuery()

expectTypeOf<
Expand All @@ -743,6 +755,10 @@ describe('"Typed" helper types', () => {
})

test('useQueryState', () => {
expectTypeOf<
TypedUseQueryState<string, void, typeof baseQuery>
>().toMatchTypeOf(api.endpoints.getTest.useQueryState)

const result = api.endpoints.getTest.useQueryState()

expectTypeOf<
Expand All @@ -761,18 +777,112 @@ describe('"Typed" helper types', () => {
})

test('useQuerySubscription', () => {
expectTypeOf<
TypedUseQuerySubscription<string, void, typeof baseQuery>
>().toMatchTypeOf(api.endpoints.getTest.useQuerySubscription)

const result = api.endpoints.getTest.useQuerySubscription()

expectTypeOf<
TypedUseQuerySubscriptionResult<string, void, typeof baseQuery>
>().toEqualTypeOf(result)
})

test('useLazyQuery', () => {
expectTypeOf<
TypedUseLazyQuery<string, void, typeof baseQuery>
>().toMatchTypeOf(api.endpoints.getTest.useLazyQuery)

const [trigger, result] = api.endpoints.getTest.useLazyQuery()

expectTypeOf<
TypedLazyQueryTrigger<string, void, typeof baseQuery>
>().toMatchTypeOf(trigger)

expectTypeOf<
TypedUseQueryHookResult<string, void, typeof baseQuery>
>().toMatchTypeOf(result)
})

test('useLazyQuery with selectFromResult', () => {
const [trigger, result] = api.endpoints.getTest.useLazyQuery({
selectFromResult: () => ({ x: true }),
})

expectTypeOf<
TypedLazyQueryTrigger<string, void, typeof baseQuery>
>().toMatchTypeOf(trigger)

expectTypeOf<
TypedUseQueryHookResult<string, void, typeof baseQuery, { x: boolean }>
>().toMatchTypeOf(result)
})

test('useLazyQuerySubscription', () => {
expectTypeOf<
TypedUseLazyQuerySubscription<string, void, typeof baseQuery>
>().toMatchTypeOf(api.endpoints.getTest.useLazyQuerySubscription)

const [trigger] = api.endpoints.getTest.useLazyQuerySubscription()

expectTypeOf<
TypedLazyQueryTrigger<string, void, typeof baseQuery>
>().toMatchTypeOf(trigger)
})

test('useMutation', () => {
expectTypeOf<
TypedUseMutation<string, void, typeof baseQuery>
>().toMatchTypeOf(api.endpoints.mutation.useMutation)

const [trigger, result] = api.endpoints.mutation.useMutation()

expectTypeOf<
TypedUseMutationTrigger<string, void, typeof baseQuery>
>().toMatchTypeOf(trigger)

expectTypeOf<
TypedUseMutationResult<string, void, typeof baseQuery>
>().toMatchTypeOf(result)
})

test('useQuery - defining selectFromResult separately', () => {
const selectFromResult = (
result: TypedUseQueryStateResult<string, void, typeof baseQuery>,
) => ({ x: true })

const result = api.endpoints.getTest.useQuery(undefined, {
selectFromResult,
})

expectTypeOf(result).toEqualTypeOf<
TypedUseQueryHookResult<
string,
void,
typeof baseQuery,
ReturnType<typeof selectFromResult>
>
>()
})

test('useMutation - defining selectFromResult separately', () => {
const selectFromResult = (
result: Omit<
TypedUseMutationResult<string, void, typeof baseQuery>,
'reset' | 'originalArgs'
>,
) => ({ x: true })

const [trigger, result] = api.endpoints.mutation.useMutation({
selectFromResult,
})
expectTypeOf(result).toEqualTypeOf<
TypedUseMutationResult<
string,
void,
typeof baseQuery,
ReturnType<typeof selectFromResult>
>
>()
})
})

0 comments on commit 1cb709b

Please sign in to comment.