Skip to content
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

Fix incorrect RTKQ endpoint definition types for correct selector typings #1818

Merged
merged 3 commits into from
Dec 10, 2021
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
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ jobs:
fail-fast: false
matrix:
node: ['14.x']
ts: ['3.9', '4.0', '4.1', '4.2', '4.3', , '4.4', '4.5', 'next']
ts: ['3.9', '4.0', '4.1', '4.2', '4.3', '4.4', '4.5', 'next']
steps:
- name: Checkout repo
uses: actions/checkout@v2
Expand Down
5 changes: 3 additions & 2 deletions packages/toolkit/src/query/endpointDefinitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -464,8 +464,9 @@ export type QueryArgFrom<D extends BaseEndpointDefinition<any, any, any>> =
export type ResultTypeFrom<D extends BaseEndpointDefinition<any, any, any>> =
D extends BaseEndpointDefinition<any, any, infer RT> ? RT : unknown

export type ReducerPathFrom<D extends EndpointDefinition<any, any, any, any>> =
D extends EndpointDefinition<any, any, any, infer RP> ? RP : unknown
export type ReducerPathFrom<
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Daaamn, good find!

D extends EndpointDefinition<any, any, any, any, any>
> = D extends EndpointDefinition<any, any, any, any, infer RP> ? RP : unknown

export type TagTypesFrom<D extends EndpointDefinition<any, any, any, any>> =
D extends EndpointDefinition<any, any, infer RP, any> ? RP : unknown
Expand Down
54 changes: 54 additions & 0 deletions packages/toolkit/src/query/tests/buildSelector.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'

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

describe('buildSelector', () => {
test.skip('buildSelector typetest', () => {
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,
},
})

const todoTitle = firstTodoTitleSelector(store.getState())

// This only compiles if we carried the types through
const upperTitle = todoTitle.toUpperCase()
expectExactType<string>(upperTitle)
})
})
32 changes: 21 additions & 11 deletions packages/toolkit/src/query/tests/optimisticUpdates.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ beforeEach(() => baseQuery.mockReset())
const api = createApi({
baseQuery: (...args: any[]) => {
const result = baseQuery(...args)
if ('then' in result)
if (typeof result === 'object' && 'then' in result)
return result
.then((data: any) => ({ data, meta: 'meta' }))
.catch((e: any) => ({ error: e }))
Expand Down Expand Up @@ -131,11 +131,16 @@ describe('basic lifecycle', () => {

describe('updateQueryData', () => {
test('updates cache values, can apply inverse patch', async () => {
baseQuery.mockResolvedValueOnce({
id: '3',
title: 'All about cheese.',
contents: 'TODO',
})
baseQuery
.mockResolvedValueOnce({
id: '3',
title: 'All about cheese.',
contents: 'TODO',
})
// TODO I have no idea why the query is getting called multiple times,
// but passing an additional mocked value (_any_ value)
// seems to silence some annoying "got an undefined result" logging
.mockResolvedValueOnce(42)
const { result } = renderHook(() => api.endpoints.post.useQuery('3'), {
wrapper: storeRef.wrapper,
})
Expand Down Expand Up @@ -180,11 +185,14 @@ describe('updateQueryData', () => {
})

test('does not update non-existing values', async () => {
baseQuery.mockResolvedValueOnce({
id: '3',
title: 'All about cheese.',
contents: 'TODO',
})
baseQuery
.mockImplementationOnce(async () => ({
id: '3',
title: 'All about cheese.',
contents: 'TODO',
}))
.mockResolvedValueOnce(42)

const { result } = renderHook(() => api.endpoints.post.useQuery('3'), {
wrapper: storeRef.wrapper,
})
Expand Down Expand Up @@ -234,6 +242,7 @@ describe('full integration', () => {
title: 'Meanwhile, this changed server-side.',
contents: 'Delicious cheese!',
})
.mockResolvedValueOnce(42)
const { result } = renderHook(
() => ({
query: api.endpoints.post.useQuery('3'),
Expand Down Expand Up @@ -283,6 +292,7 @@ describe('full integration', () => {
title: 'Meanwhile, this changed server-side.',
contents: 'TODO',
})
.mockResolvedValueOnce(42)

const { result } = renderHook(
() => ({
Expand Down