redux 中的安装类型 - 类型 'never' 上不存在属性 x



我已经在Typescript中设置了我的redux存储,如下所示。然而,当我试图在主组件IDE中使用useSelector获取火箭时,出现错误

const rockets = useSelector((state: RootState) => state.rocketList.rockets);

错误消息-类型"never"上不存在属性"rockets">

配置Store.tsx


import { combineReducers, createStore } from "redux";
import rocketsReducer from "./ducks/rockets";
export const rootReducer = combineReducers({
rocketList: rocketsReducer,
});
const store = createStore(rootReducer);
export default store;

rockets.tsx(这遵循1个文件中的动作、减速器和类型的鸭子模式(

import { IAction, IRocket } from "../../Interfaces";
const STOREROCKETS = "storeRockets";
export const storeRockets = (rockets: IAction) => ({
type: STOREROCKETS,
payload: rockets,
});
type RocketState = {
rockets: IRocket[]
}
const initialState: RocketState = {
rockets: [],
};
export default (state:RocketState = initialState, action: IAction) => {
switch (action.type) {
case STOREROCKETS:
return { ...state, rockets: action.payload };
default:
return state;
}
};

接口.ts

import { rootReducer } from "./redux/configureStore";
export type RootState = ReturnType<typeof rootReducer>
export interface IRockets {
rockets: IRocket[]
}
export interface IAction {
type: string
payload: { type: string, payload: object[] }
}
export interface IRocket {
id: string
name: string
description: string
success_rate_pct: number
active: boolean
first_flight: string
wikipedia: string
cost_per_launch: number
flickr_images: string[]
}

主页.tsx

import { RootState } from "../Interfaces";
const Home: FC = () => {
const [isLoading, setIsLoading] = useState<Boolean>(false);
const dispatch = useDispatch();
const [showError, setShowError] = useState<Boolean>(false);
const [errorText, setErrorText] = useState<String>("");
const rockets = useSelector((state: RootState) => state.rocketList.rockets);

在动作类型的定义中有过多的对象嵌套:

export interface IAction {
type: string
payload: { type: string, payload: object[] }
}

和行动创造者:

export const storeRockets = (rockets: IAction) => ({
type: STOREROCKETS,
payload: rockets,
});

假设我有一系列火箭:

const rockets: IRocket[] = [];

我希望称动作创作者为:

storeRockets(rockets);

得到这样的结果:

{
type: "storeRockets",
payload: [],
}

但相反,你的类型决定了你必须这样称呼它:

storeRockets({
type: "sometype",
payload: { 
type: "otherType",
payload: rockets 
}
})

然后动作创建者添加另一个级别的type!所以你的实际行动是:

{
type: "storeRockets",
payload: {
type: "sometype",
payload: {
type: "otherType",
payload: [],
}
}
}

这是代码中的主要问题。


您应该将您的操作类型更改为此。它修复了嵌套问题,还使用了特定的对象类型IRocket而不是object

export interface IAction {
type: string;
payload: IRocket[]
}

您的动作创建者应该只执行payload,而不是整个动作。它返回一个IAction

export const storeRockets = (rockets: IRocket[]): IAction => ({
type: STOREROCKETS,
payload: rockets
});

我建议您在reducer上设置一个显式返回类型,这样,如果您没有像以前那样返回预期的类型,就会出现错误。

export default (state: RocketState = initialState, action: IAction): RocketState => {

我还建议您创建一个已经知道RootState类型的useSelector钩子,这样您就不必每次都声明它。

import { createSelectorHook } from "react-redux";
export const useSelector = createSelectorHook<RootState>();

最新更新