当我从 Typescript 中的 createEntityAdapter 获取选择器时出现错误
Getting the Error when I get selectors from createEntityAdapter in Typescript
在开发一个简单的宠物项目时,我遇到了一个错误,不知道如何修复它。
我是 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 | )
如何解决?
如果您想 运行 宠物项目。遵循此 link:https://github.com/AlexKor-5/ReactPizzaApp_Ts/tree/27028d4275fef75a70eb6b0b4b129e5bf5997e78(但更改 apiSlice 文件的末尾,使其与 Stack Overflow 当前页面上显示的文件相对应)。
(src/features/api/apiSlice.ts )
您必须为 state
提供类型。
(state: RootState) => selectPizzasData(state) ?? initialState
根据@phry 的初始回复,我认为问题出在您的 transformResponse
功能上:
transformResponse: (responseData: PizzaResponseType[]) => {
pizzasAdapter.setAll(initialState, responseData)
return responseData
},
该代码有几个问题:
- 您return使用原始
responseData
,它仍然是PizzaResponseType[]
。这告诉 TS 结果是 also a PizzaResponseType[]
,而它 should 是 EntityState<Pizza>
.
- 为了实现这一点,您需要 return 来自
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
)
所有这些更改后,错误消失了。
在开发一个简单的宠物项目时,我遇到了一个错误,不知道如何修复它。 我是 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 | )
如何解决?
如果您想 运行 宠物项目。遵循此 link:https://github.com/AlexKor-5/ReactPizzaApp_Ts/tree/27028d4275fef75a70eb6b0b4b129e5bf5997e78(但更改 apiSlice 文件的末尾,使其与 Stack Overflow 当前页面上显示的文件相对应)。 (src/features/api/apiSlice.ts )
您必须为 state
提供类型。
(state: RootState) => selectPizzasData(state) ?? initialState
根据@phry 的初始回复,我认为问题出在您的 transformResponse
功能上:
transformResponse: (responseData: PizzaResponseType[]) => {
pizzasAdapter.setAll(initialState, responseData)
return responseData
},
该代码有几个问题:
- 您return使用原始
responseData
,它仍然是PizzaResponseType[]
。这告诉 TS 结果是 also aPizzaResponseType[]
,而它 should 是EntityState<Pizza>
. - 为了实现这一点,您需要 return 来自
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
)
所有这些更改后,错误消失了。