0

嘿,这里是打字稿的新手,尤其是 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;
  }
};

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

4

3 回答 3

0

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

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

您可能正在关注一个非常过时的教程。

我建议您阅读官方的Redux Essentials 教程,该教程将教您使用 Redux Toolkit(在 JavaScript 级别上)进行 Redux,然后阅读Redux Toolkit TypeScript QuickStart。如果您对如何使用 TypeScript 有任何疑问,Redux Toolkit Api Reference(此处为 createSlice)中的所有示例都可以在 TypeScript 和 JavaScript 中使用。

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

于 2021-06-26T08:32:59.567 回答
0

因为您正在使用combinereducers所以需要initialvalue在创建时通过userLoginReducer

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

您可以在createstore中阅读更多内容

[preloadedState] (any):初始状态。您可以选择指定它以在通用应用程序中混合来自服务器的状态,或恢复以前序列化的用户会话。如果您使用 combineReducers 生成 reducer,则这必须是一个普通对象,其形状与传递给它的键的形状相同。否则,您可以自由传递您的减速器可以理解的任何内容。

于 2021-06-26T02:30:10.987 回答
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 为您提供更好的错误消息,并且还会在您继续构建应用程序时为您的成功做好准备。

于 2021-06-26T02:37:48.477 回答