You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用combineReducers组合多Reducer遇TypeScript state属性未知错误

Redux + TypeScript:State属性无法识别的问题解决

问题场景

我按如下方式配置Redux Store:

const rootReducer = combineReducers({
    login: loginReducer,
    counter: counterReducer
});

const store = configureStore({
    reducer: rootReducer
});

login切片代码:

import { createSlice } from '@reduxjs/toolkit';

const loginSlice = createSlice({
    name: 'login',
    initialState: {
        isLoggedIn: false,
    },
    reducers: {
        login: (state) => {
            state.isLoggedIn = true;
        },
        logout: (state) => {
            state.isLoggedIn = false;
        },
    },
});

export const { login, logout } = loginSlice.actions;

export default loginSlice.reducer;

counter切片代码:

import { createSlice } from '@reduxjs/toolkit';

export const counterSlice = createSlice({
    name: 'counter',
    initialState: {
        counterValue: 0,
    },
    reducers: {
        increment: (state) => {
            state.counterValue += 1;
        },
        decrement: (state) => {
            state.counterValue -= 1;
        },
        incrementByAmount: (state, action) => {
            state.counterValue += action.payload;
        },
    },
});

export const { increment, decrement, incrementByAmount } = counterSlice.actions;

export default counterSlice.reducer;

尝试通过useSelector((state) => state.counter.counterValue)或useSelector((state) => state.login.isLoggedIn)访问状态时,出现TypeScript错误:Property 'counter' does not exist on type 'unknown';直接访问state.counterValue返回undefined。

问题原因

TypeScript无法自动推断Redux store的state结构,默认将useSelector的state参数类型设为unknown,因此访问state.counter这类属性时会触发类型错误。而直接访问state.counterValue返回undefined,是因为store的顶层state是由combineReducers定义的包含login和counter子对象的结构,counterValue属于counter子对象下的属性,必须通过层级访问。

解决方法

方法1:导出RootState类型并手动指定

在定义store的文件中,添加类型推导:

// 从store.getState的返回值推导RootState类型
export type RootState = ReturnType<typeof store.getState>;

在组件中使用useSelector时,指定state类型:

import { useSelector } from 'react-redux';
import type { RootState } from './path-to-your-store-file';

const counterValue = useSelector((state: RootState) => state.counter.counterValue);
const isLoggedIn = useSelector((state: RootState) => state.login.isLoggedIn);

方法2:创建自定义Typed Selector钩子(推荐)

为了避免重复手动指定类型,创建一个自定义的useAppSelector钩子:

// 比如在src/hooks.ts文件中
import { useSelector, TypedUseSelectorHook } from 'react-redux';
import type { RootState } from './path-to-your-store-file';

export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;

之后在组件中直接使用该钩子,无需再手动指定类型:

import { useAppSelector } from './hooks';

const counterValue = useAppSelector(state => state.counter.counterValue);
const isLoggedIn = useAppSelector(state => state.login.isLoggedIn);

内容的提问来源于stack exchange,提问作者erol_smsr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 05:25:24