File size: 2,769 Bytes
11811dc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'

import { configureStore, createSelector } from '@reduxjs/toolkit'

describe('type tests', () => {
  test('buildSelector type test', () => {
    interface Todo {
      userId: number
      id: number
      title: string
      completed: boolean
    }

    type Todos = Array<Todo>

    const exampleApi = createApi({
      reducerPath: 'api',
      baseQuery: fetchBaseQuery({
        baseUrl: 'https://jsonplaceholder.typicode.com',
      }),
      endpoints: (build) => ({
        getTodos: build.query<Todos, string>({
          query: () => '/todos',
        }),
      }),
    })

    const exampleQuerySelector = exampleApi.endpoints.getTodos.select('/')

    const todosSelector = createSelector(
      [exampleQuerySelector],
      (queryState) => {
        return queryState?.data?.[0] ?? ({} as Todo)
      },
    )

    const firstTodoTitleSelector = createSelector(
      [todosSelector],
      (todo) => todo?.title,
    )

    const store = configureStore({
      reducer: {
        [exampleApi.reducerPath]: exampleApi.reducer,
        other: () => 1,
      },
    })

    const todoTitle = firstTodoTitleSelector(store.getState())

    // This only compiles if we carried the types through
    const upperTitle = todoTitle.toUpperCase()

    expectTypeOf(upperTitle).toBeString()
  })

  test('selectCachedArgsForQuery type test', () => {
    interface Todo {
      userId: number
      id: number
      title: string
      completed: boolean
    }

    type Todos = Array<Todo>

    const exampleApi = createApi({
      reducerPath: 'api',
      baseQuery: fetchBaseQuery({
        baseUrl: 'https://jsonplaceholder.typicode.com',
      }),
      endpoints: (build) => ({
        getTodos: build.query<Todos, string>({
          query: () => '/todos',
        }),
        getInfiniteTodos: build.infiniteQuery<Todos, string, number>({
          infiniteQueryOptions: {
            initialPageParam: 0,
            maxPages: 3,
            getNextPageParam: (
              lastPage,
              allPages,
              lastPageParam,
              allPageParams,
            ) => lastPageParam + 1,
          },
          query({ pageParam }) {
            return `/todos?page=${pageParam}`
          },
        }),
      }),
    })

    const store = configureStore({
      reducer: {
        [exampleApi.reducerPath]: exampleApi.reducer,
        other: () => 1,
      },
    })

    expectTypeOf(
      exampleApi.util.selectCachedArgsForQuery(store.getState(), 'getTodos'),
    ).toEqualTypeOf<string[]>()
    expectTypeOf(
      exampleApi.util.selectCachedArgsForQuery(
        store.getState(),
        'getInfiniteTodos',
      ),
    ).toEqualTypeOf<string[]>()
  })
})