While developing a simple pet project, I faced an error, without knowing how to fix it. I am new to Typescript, and judging by a message error the mistake is in TS. The error message appears after adding this snippet into the file 'apiSlice.ts'.
export const { selectAll: selectAllPizzas } = pizzasAdapter.getSelectors(
state => selectPizzasData(state) ?? initialState
)
The error text looks like this:
ERROR in src/features/api/apiSlice.ts:44:31
TS2345: Argument of type 'unknown' is not assignable to parameter of type '{ api: CombinedState<{ getPizzas: QueryDefinition<void, BaseQueryFn<string | FetchArgs, unknown,
FetchBaseQueryError, {}, FetchBaseQueryMeta>, never, PizzaResponseType[], "api">; }, never, "api">; }'.
42 | //
43 | export const { selectAll: selectAllPizzas } = pizzasAdapter.getSelectors(
> 44 | state => selectPizzasData(state) ?? initialState
| ^^^^^
45 | )
46 |
The whole file: (Pay attention to the last three rows)
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
import { createEntityAdapter, createSelector } from '@reduxjs/toolkit'
const pizzasAdapter = createEntityAdapter()
const initialState = pizzasAdapter.getInitialState()
interface PizzaResponseType {
id: string
name: string
image: string
price: number
currencySign: string
popularityPoint: number
type: string
description: string
spec: string
}
export const apiSlice = createApi({
reducerPath: 'api',
baseQuery: fetchBaseQuery({ baseUrl: '' }),
endpoints: builder => ({
getPizzas: builder.query<PizzaResponseType[], void>({
query: () => '/pizzas',
transformResponse: (responseData: PizzaResponseType[]) => {
pizzasAdapter.setAll(initialState, responseData)
return responseData
},
}),
}),
})
export const { useGetPizzasQuery } = apiSlice
export const selectPizzasResult = apiSlice.endpoints.getPizzas.select()
// console.log(selectPizzasResult)
export const selectPizzasData = createSelector(
selectPizzasResult,
pizzasResult => pizzasResult.data
)
//
export const { selectAll: selectAllPizzas } = pizzasAdapter.getSelectors(
state => selectPizzasData(state) ?? initialState
)
The RootState was imported from the store.ts file, where I configured the store as it was witten in the Redux Toolkit documentation. The store.ts file:
const store = configureStore({
reducer: {
pizzas:pizzaSlice,
[apiSlice.reducerPath]: apiSlice.reducer,
},
middleware: getDefaultMiddleware => getDefaultMiddleware().concat(apiSlice.middleware),
})
export type RootState = ReturnType<typeof store.getState>
export default store
That imported RootState type was inserted for the state in the parameter:
export const { selectAll: selectAllPizzas } = pizzasAdapter.getSelectors(
(state: RootState) => selectPizzasData(state) ?? initialState
)
and this change does nothing. The error appears anyway:
ERROR in src/features/api/apiSlice.ts:46:5
TS2345: Argument of type '(state: RootState) => EntityState<unknown> | PizzaResponseType[]' is not assignable to parameter of type '(state: { pizzas: EntityState<unknown>; api: CombinedState<{ getPizzas: Query
Definition<void, BaseQueryFn<string | FetchArgs, unknown, FetchBaseQueryError, {}, FetchBaseQueryMeta>, never, PizzaResponseType[], "api">; }, never, "api">; }) => EntityState<...>'.
Type 'EntityState<unknown> | PizzaResponseType[]' is not assignable to type 'EntityState<unknown>'.
Type 'PizzaResponseType[]' is missing the following properties from type 'EntityState<unknown>': ids, entities
44 |
45 | export const { selectAll: selectAllPizzas } = pizzasAdapter.getSelectors(
> 46 | (state: RootState) => selectPizzasData(state) ?? initialState
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
47 | )
How to fix it?
In case you want to run the pet project. Follow this link:https://github.com/AlexKor-5/ReactPizzaApp_Ts/tree/27028d4275fef75a70eb6b0b4b129e5bf5997e78 (but change the end of the apiSlice file so it corresponds to the file which is shown on the current page of Stack Overflow). (src/features/api/apiSlice.ts )
CodePudding user response:
You have to give a type for state
.
(state: RootState) => selectPizzasData(state) ?? initialState
CodePudding user response:
Following on from @phry 's initial response, I think the issue is your transformResponse
function:
transformResponse: (responseData: PizzaResponseType[]) => {
pizzasAdapter.setAll(initialState, responseData)
return responseData
},
That code has a couple problems:
- You're returning the original
responseData
, which is still aPizzaResponseType[]
. That tells TS that the result is also aPizzaResponseType[]
, when what it should be is anEntityState<Pizza>
. - In order to make that happen, you need to return the value from
pizzasAdapter.setAll()
instead.