Skip to content

Commit e1be806

Browse files
committed
Add type tests for the TypedQueryStateSelector type
1 parent 53cd841 commit e1be806

File tree

1 file changed

+113
-2
lines changed

1 file changed

+113
-2
lines changed

packages/toolkit/src/query/tests/buildHooks.test-d.tsx

Lines changed: 113 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
1-
import type { UseMutation, UseQuery } from '@internal/query/react/buildHooks'
1+
import type {
2+
QueryStateSelector,
3+
UseMutation,
4+
UseQuery,
5+
} from '@internal/query/react/buildHooks'
26
import { ANY } from '@internal/tests/utils/helpers'
37
import type { SerializedError } from '@reduxjs/toolkit'
4-
import type { SubscriptionOptions } from '@reduxjs/toolkit/query/react'
8+
import type {
9+
QueryDefinition,
10+
SubscriptionOptions,
11+
TypedQueryStateSelector,
12+
} from '@reduxjs/toolkit/query/react'
513
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
614
import { useState } from 'react'
715

@@ -260,4 +268,107 @@ describe('type tests', () => {
260268
api.endpoints.updateUser.useMutation,
261269
)
262270
})
271+
272+
test('TypedQueryStateSelector creates a pre-typed version of QueryStateSelector', () => {
273+
type Post = {
274+
id: number
275+
title: string
276+
}
277+
278+
type PostsApiResponse = {
279+
posts: Post[]
280+
total: number
281+
skip: number
282+
limit: number
283+
}
284+
285+
type QueryArgument = number | undefined
286+
287+
type BaseQueryFunction = ReturnType<typeof fetchBaseQuery>
288+
289+
type SelectedResult = Pick<PostsApiResponse, 'posts'>
290+
291+
const postsApiSlice = createApi({
292+
baseQuery: fetchBaseQuery({ baseUrl: 'https://dummyjson.com/posts' }),
293+
reducerPath: 'postsApi',
294+
tagTypes: ['Posts'],
295+
endpoints: (build) => ({
296+
getPosts: build.query<PostsApiResponse, QueryArgument>({
297+
query: (limit = 5) => `?limit=${limit}&select=title`,
298+
}),
299+
}),
300+
})
301+
302+
const { useGetPostsQuery } = postsApiSlice
303+
304+
function PostById({ id }: { id: number }) {
305+
const { post } = useGetPostsQuery(undefined, {
306+
selectFromResult: (state) => ({
307+
post: state.data?.posts.find((post) => post.id === id),
308+
}),
309+
})
310+
311+
expectTypeOf(post).toEqualTypeOf<Post | undefined>()
312+
313+
return <li>{post?.title}</li>
314+
}
315+
316+
const EMPTY_ARRAY: Post[] = []
317+
318+
const typedSelectFromResult: TypedQueryStateSelector<
319+
PostsApiResponse,
320+
QueryArgument,
321+
BaseQueryFunction,
322+
SelectedResult
323+
> = (state) => ({ posts: state.data?.posts ?? EMPTY_ARRAY })
324+
325+
expectTypeOf<
326+
TypedQueryStateSelector<
327+
PostsApiResponse,
328+
QueryArgument,
329+
BaseQueryFunction,
330+
SelectedResult
331+
>
332+
>().toEqualTypeOf<
333+
QueryStateSelector<
334+
SelectedResult,
335+
QueryDefinition<
336+
QueryArgument,
337+
BaseQueryFunction,
338+
string,
339+
PostsApiResponse
340+
>
341+
>
342+
>()
343+
344+
expectTypeOf(typedSelectFromResult).toEqualTypeOf<
345+
QueryStateSelector<
346+
SelectedResult,
347+
QueryDefinition<
348+
QueryArgument,
349+
BaseQueryFunction,
350+
string,
351+
PostsApiResponse
352+
>
353+
>
354+
>()
355+
356+
function PostsList() {
357+
const { posts } = useGetPostsQuery(undefined, {
358+
selectFromResult: typedSelectFromResult,
359+
})
360+
361+
expectTypeOf(posts).toEqualTypeOf<Post[]>()
362+
363+
return (
364+
<div>
365+
<ul>
366+
{posts.map((post) => (
367+
<PostById key={post.id} id={post.id} />
368+
))}
369+
</ul>
370+
</div>
371+
)
372+
}
373+
})
263374
})

0 commit comments

Comments
 (0)