Typescript redux - 输入 '{ userInfo: any; }' 不可分配给类型 'undefined'

时间:2021-06-26 01:12:01

标签: reactjs typescript redux

大家好,这里是 typescript 的新手,尤其是 redux。如标题所述,我的商店中的初始状态会弹出该问题。错误的顶部 - Argument of type '{ userLogin: { userInfo: any; }; }' is not assignable to parameter of type '{ userLogin?: undefined; }'

商店

import { createStore, combineReducers, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import { composeWithDevTools } from "redux-devtools-extension";
import { userLoginReducer } from "./user/reducer";



export type RootState = ReturnType<typeof store.getState>;

const reducer = combineReducers({
  userLogin: userLoginReducer,
});

const userInfoFromStorage = localStorage.getItem("userInfo")
  ? JSON.parse(localStorage.getItem("userInfo")!)
  : null;

const initialState = {
  userLogin: { userInfo: userInfoFromStorage },
};

const middleware = [thunk];

export const store = createStore(
  reducer,
  initialState,
  composeWithDevTools(applyMiddleware(...middleware))
);
Argument of type '{ userLogin: { userInfo: any; }; }' is not assignable to parameter of type '{ userLogin?: undefined; }'.
  Types of property 'userLogin' are incompatible.
    Type '{ userInfo: any; }' is not assignable to type 'undefined'.ts(2345)
const initialState: {
    userLogin: {
        userInfo: any;
    };
}

减速器

import { Store } from "redux";
import {
  USER_LOGIN_REQUEST,
  USER_LOGIN_SUCCESS,
  USER_LOGIN_FAIL,
  USER_LOGOUT,
  UserActionTypes,
} from "./types";

export const userLoginReducer = (state: Store, action: UserActionTypes) => {
  switch (action.type) {
    case USER_LOGIN_REQUEST:
      return { loading: true };

    case USER_LOGIN_SUCCESS:
      return { loading: false, userInfo: action.payload };

    case USER_LOGIN_FAIL:
      return { loading: false, error: action.payload };

    case USER_LOGOUT:
      return {};

    default:
      return state;
  }
};

我写这个是因为我得到了大部分代码的错误

3 个答案:

答案 0 :(得分:0)

因为您使用的是 combinereducers,所以在创建 initialvalue 时需要传递 userLoginReducer

export const userLoginReducer = (state = { userInfo: userInfoFromStorage }, action: UserActionTypes) => {...}

您可以在createstore

中阅读更多内容 <块引用>

[preloadedState] (any):初始状态。您可以选择指定 它在通用应用程序中从服务器获取状态,或者 恢复先前序列化的用户会话。如果你生产减速机 使用 combineReducers,这必须是具有相同形状的普通对象 作为传递给它的键。否则,您可以随意通过任何东西 您的减速器可以理解。

答案 1 :(得分:0)

这一行: export type RootState = ReturnType<typeof store.getState>; 是有问题的,因为打字稿必须跳过很多圈子才能弄清楚 store.getState 的返回类型是什么。由于没有定义根状态应该是什么样子的接口或类型,打字稿试图通过查看初始状态来确定根状态的类型,这不是您生命周期中所有可能值的完整图片应用。

一个好的起点是定义一个 interface 来定义整个商店中的预期类型,然后在所有引用状态的地方引用该接口,如下所示:

interface RootState {
  userLogin: { loading?: boolean, userInfo: any },
};

const initialState: RootState = {
  userLogin: { userInfo: userInfoFromStorage },
};

上述内容可能无法解决您的问题,但它可能会导致 typescript 为您提供更好的错误消息,并且还会让您在继续构建应用程序时取得成功。

答案 2 :(得分:0)

您需要正确输入 userLoginReducer 形状 - state: Store, 不正确,因为它会将 reducer 的数据输入为成熟的 Redux 存储。

一般来说,我建议你从你现在编写的代码退后一步,因为它显示了一种非常过时的 Redux 类型,我们不再推荐(多年!)用于新项目,并且与 TypeScript 一起使用特别烦人,因为它需要大量额外的代码。

您可能正在学习一个非常过时的教程。

我建议您阅读官方的 Redux Essentials tutorial,它会教您 Redux 和 Redux Toolkit(在 JavaScript 级别),然后阅读 Redux Toolkit TypeScript QuickStart。如果您对如何将其与 TypeScript 结合使用还有任何疑问,Redux Toolkit Api Reference (here createSlice) 中的所有示例都可以在 TypeScript 和 JavaScript 中使用。

如您所见,使用 TypeScript 只需要在这里和那里进行一些注释,并且不需要您执行诸如创建联合操作类型之类的事情,在这一点上我们认为这是一种反模式。