在 Reduxjs/toolkit 的状态切片中使用打字稿

Using typescript in state slices of Reduxjs/toolkit

我是 React 世界的新手,我正在尝试使用 NextJs + reduxjs/toolkit 以及 MUI 和 TypeScript 编写应用程序。 我在 reduxjs/toolkit 的 TypeScript 部分遇到问题。 这是我的 **store/user-preferences-silce.ts **

import { ThemeOptions } from "@mui/material";
import { createSlice } from "@reduxjs/toolkit";
import { defaultThemeOption } from "../styles/theme/themeOptions";

export type UserPreferencesSliceState = {
  theme: ThemeOptions;
};

const initialState: UserPreferencesSliceState = {
  theme: defaultThemeOption,
};

const userPreferencesSlice = createSlice({
  name: "userPreferences",
  initialState,
  reducers: {
    toggleThemeMode(state) {
      state.theme!.palette!.mode =
        state.theme!.palette!.mode === "light" ? "dark" : "light";
    },
  },
});

export const userPreferencesActions = userPreferencesSlice.actions;
export default userPreferencesSlice.reducer;

然后我的store/index.ts

import { configureStore } from "@reduxjs/toolkit";
import userPreferencesReducer from "./user-preferences-slice";

const store = configureStore({
  reducer: {
    userPreferences: userPreferencesReducer,
  },
});

// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<typeof store.getState>;
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch;

export default store;

但是当我使用 Layout.tsx

中的状态时
import { createTheme, ThemeProvider } from "@mui/material/styles";
import { useSelector } from "react-redux";
import { RootState } from "../../store";
import { ThemeOptions } from "@mui/material";
import { useMemo } from "react";

const Layout: React.FC = (props) => {
  const themeOptions: ThemeOptions = useSelector<RootState>(
    (state) => state.userPreferences.theme
  );
  const theme = useMemo(() => {
    return createTheme(themeOptions);
  }, [themeOptions]);

  return <ThemeProvider theme={theme}>{props.children}</ThemeProvider>;
};

export default Layout;

我收到这个警告

Type 'unknown' not assignable to type 'ThemeOptions'

参考这部分

 const themeOptions: ThemeOptions = useSelector<RootState>(
    (state) => state.userPreferences.theme
  );

有人可以帮助我了解如何处理 redux 切片的类型吗?谢谢

如你所见in the useSelector type definition,钩子接受两种泛型:第一种TState是存储状态类型,第二种Selected是选择器return 类型。默认情况下,两个泛型都是可选的,return 类型是 unknown,这就是 TypeScript 抱怨的原因。

对此有两种可能的解决方案:

  1. 您可以通过传递 ThemeOptions 作为第二个通用类型来显式声明您的选择器的预期 return 类型:

    const themeOptions: ThemeOptions = useSelector<RootState, ThemeOptions>(/* ... */)
    
  2. 或者使用 type inference:

    将工作留给 TypeScript
    const themeOptions = useSelector((state: RootState) => state.userPreferences.theme)
    

    请注意我是如何删除通用 <RootState> 声明并将其声明添加到选择器参数的。这样,它将从方法签名中推断出 TState,并从其 return 类型中推断出 Selected。此外,我删除了 const 上的 : ThemeOptions 类型声明以进一步推断类型,这是可选的。