从Typescript中的createEntityAdapter获取选择器时出错



在开发一个简单的pet项目时,我遇到了一个错误,不知道如何修复它。我是Typescript的新手,根据消息错误判断错误在TS中。将此代码段添加到文件"apiSlice.ts"后会出现错误消息。

export const { selectAll: selectAllPizzas } = pizzasAdapter.getSelectors(
state => selectPizzasData(state) ?? initialState
)

错误文本如下所示:

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 |

整个文件:(注意最后三行)

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
)

RootState是从store.ts文件导入的,我在那里按照Redux Toolkit文档中的提示配置了存储。store.ts文件:

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

已为参数中的状态插入导入的RootState类型:

export const { selectAll: selectAllPizzas } = pizzasAdapter.getSelectors(
(state: RootState) => selectPizzasData(state) ?? initialState
)

而这种改变毫无作用。错误仍然出现:

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 | )

如何修复?

如果你想运行宠物项目。关注此链接:https://github.com/AlexKor-5/ReactPizzaApp_Ts/tree/27028d4275fef75a70eb6b0b4b129e5bf5997e78(但更改apiSlice文件的末尾,使其与Stack Overflow当前页面上显示的文件相对应)。(src/features/api/apiSlice.ts)

同样,当我写<EntityState<PizzaResponseType>时,它应该是什么样子

getPizzas: builder.query<EntityState<PizzaResponseType>, void>({
query: () => '/pizzas',
transformResponse: (responseData: PizzaResponseType[]) => {
return pizzasAdapter.setAll(pizzaInitialState,responseData)
},
}),

我得到另一个错误:

TS2322: Type '(responseData: IPizzaType[]) => EntityState<unknown>' is not assignable to type '(baseQueryReturnV
alue: unknown, meta: FetchBaseQueryMeta | undefined, arg: void) => EntityState<IPizzaType> | Promise<EntityState
<IPizzaType>>'.
Type 'EntityState<unknown>' is not assignable to type 'EntityState<IPizzaType> | Promise<EntityState<IPizzaTyp
e>>'.
Type 'EntityState<unknown>' is not assignable to type 'EntityState<IPizzaType>'.
Type 'unknown' is not assignable to type 'IPizzaType'.
28 |         getPizzas: builder.query<EntityState<IPizzaType>, void>({
29 |             query: () => '/pizzas',
> 30 |             transformResponse: (responseData: IPizzaType[]) => {
|             ^^^^^^^^^^^^^^^^^
31 |                 return pizzasAdapter.setAll(pizzaInitialState, responseData)
32 |             },
33 |         }),

又出什么问题了?

您必须为state指定一个类型。

(state: RootState) => selectPizzasData(state) ?? initialState

根据@phry的初始响应,我认为问题是您的transformResponse函数:

transformResponse: (responseData: PizzaResponseType[]) => {
pizzasAdapter.setAll(initialState, responseData)
return responseData
},

该代码有几个问题:

  • 您正在返回原始responseData,它仍然是PizzaResponseType[]。这告诉TS结果是也是PizzaResponseType[],而应该是EntityState<Pizza>
  • 为了实现这一点,您需要从pizzasAdapter.setAll()返回值

我用这种方式重新拨号:

getPizzas: builder.query<EntityState<unknown>, void>({
query: () => '/pizzas',
transformResponse: (responseData: PizzaResponseType[]) => {
return pizzasAdapter.setAll(initialState, responseData)
},
}),

再加上这个片段:

export const { selectAll: selectAllPizzas } = pizzasAdapter.getSelectors(
(state: RootState) => selectPizzasData(state) ?? initialState
)

在所有这些更改之后,错误消失了。

最新更新