在开发一个简单的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
)
在所有这些更改之后,错误消失了。