React+Redux项目中TypeScript提示state为unknown类型的问题求助
解决React+Redux中useSelector提示"state is of type unknown"的问题
这个错误的核心原因是TypeScript无法识别你的Redux Store根状态的类型,所以默认将state标记为unknown类型。代码能正常运行是因为TypeScript的类型检查仅在编译阶段生效,最终运行的是转译后的JavaScript,类型错误不会阻塞代码执行——但这相当于放弃了TypeScript的类型安全优势,后续修改代码时容易出现隐式错误。
以下是完整的解决方案:
1. 定义Redux根状态与Dispatch类型
首先找到你的Redux Store配置文件(通常是src/redux/store.ts),导出根状态和Dispatch的类型:
import { configureStore } from '@reduxjs/toolkit'; import usersReducer from './slices/users'; // 创建Store export const store = configureStore({ reducer: { users: usersReducer, // 其他reducer请在这里添加 }, }); // 导出根状态类型:通过store.getState的返回值自动推导 export type RootState = ReturnType<typeof store.getState>; // 导出类型化的Dispatch export type AppDispatch = typeof store.dispatch;
2. 创建类型化的自定义Hooks
在同一个Store文件或单独的hooks文件中,定义类型化的useAppSelector和useAppDispatch,避免每次使用都手动指定类型:
import { useSelector, useDispatch, TypedUseSelectorHook } from 'react-redux'; import { RootState, AppDispatch } from './store'; // 类型化的useSelector,自动识别RootState类型 export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector; // 类型化的useDispatch,自动识别AppDispatch类型 export const useAppDispatch = () => useDispatch<AppDispatch>();
3. 替换组件中的原Hooks
回到你的Users组件,替换原来的useSelector和useDispatch,同时移除as any的类型断言:
// React Imports import React, { useEffect } from "react"; // MUI Imports import Navbar from "../../Components/Navbar"; import Grid from "@mui/material/Grid"; import Box from "@mui/material/Box"; import Card from "@mui/material/Card"; import CardContent from "@mui/material/CardContent"; import { CardMedia } from "@mui/material"; import Typography from "@mui/material/Typography"; // Redux Imports:替换为自定义的类型化Hooks import { fetchAllUsers } from "../../redux/slices/users"; import { useAppSelector, useAppDispatch } from "../../redux/store"; function Users() { // 现在state会自动识别RootState类型,不再提示unknown const { list: users } = useAppSelector((state) => state.users); const dispatch = useAppDispatch(); useEffect(() => { // 无需再用as any,dispatch已自动匹配异步action的类型 dispatch(fetchAllUsers()); }, [dispatch]); // 组件返回部分保持不变... } export default Users;
4. (可选但推荐)给Users切片定义状态类型
为了更完整的类型安全,在users切片文件中定义用户和状态的类型:
// src/redux/slices/users.ts import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; // 定义单个用户的类型 export type User = { id: number; first_name: string; last_name: string; email: string; avatar: string; }; // 定义Users切片的状态类型 type UsersState = { list: User[]; loading: boolean; error: string | null; }; // 初始状态 const initialState: UsersState = { list: [], loading: false, error: null, }; // 异步Thunk(根据你的API返回结构调整) export const fetchAllUsers = createAsyncThunk('users/fetchAll', async () => { const response = await fetch('你的用户API地址'); const data = await response.json(); return data.data; // 假设API返回的用户列表在data字段中 }); const usersSlice = createSlice({ name: 'users', initialState, reducers: {}, extraReducers: (builder) => { builder .addCase(fetchAllUsers.pending, (state) => { state.loading = true; }) .addCase(fetchAllUsers.fulfilled, (state, action) => { state.loading = false; state.list = action.payload; }) .addCase(fetchAllUsers.rejected, (state, action) => { state.loading = false; state.error = action.error.message || '加载用户列表失败'; }); }, }); export default usersSlice.reducer;
这样整个流程的类型就完全闭环了,既消除了类型错误提示,又保留了TypeScript的类型检查能力,后续修改代码时能及时发现潜在问题。
内容的提问来源于stack exchange,提问作者Omar Russo Castillo
相关产品推荐
相关产品推荐

