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

使用TypeScript开发Redux时无法将State映射到Props的问题求助

解决TypeScript中Redux State映射到Props的问题

我猜你在把JavaScript版的Redux教程转成TypeScript时,卡在了State到Props的映射环节。先把你给出的代码片段补全梳理清楚,再一步步解决这个问题。

先梳理你的现有代码(补全片段)

你提供的App.tsx大概是这样的:

import * as React from 'react';
import Todo from '../models/Todo';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import Main from './Main';

export interface State {
  todoList: Todo[];
  filterStatus: string;
  isAdding: boolean;
}

const defaultState: State = {
  todoList: [],
  filterStatus: 'SHOW_ALL',
  isAdding: false,
};

const reducer = (state: State = defaultState, action: any) => {
  // 你的reducer逻辑应该在这里
  switch(action.type) {
    // 比如添加todo、切换筛选状态等逻辑
    default:
      return state;
  }
};

const store = createStore(reducer);

const App = () => {
  return (
    <Provider store={store}>
      <Main />
    </Provider>
  );
};

export default App;

常见问题及两种解决方式

在TypeScript中用Redux做状态映射,核心问题是类型定义不完整,下面分两种常用场景说明解决方案:

方式1:用useSelector(函数组件推荐)

如果你的Main.tsx是函数组件,用useSelector获取状态时,需要明确指定State的类型,让TypeScript识别状态结构:

// Main.tsx
import * as React from 'react';
import { useSelector } from 'react-redux';
import { State } from './App'; // 导入全局State类型

const Main = () => {
  // 给useSelector指定State类型,精准选取需要的状态
  const todoList = useSelector((state: State) => state.todoList);
  const filterStatus = useSelector((state: State) => state.filterStatus);
  const isAdding = useSelector((state: State) => state.isAdding);

  return (
    <div>
      <h2>Todo List</h2>
      {todoList.map(todo => (
        <div key={todo.id}>{todo.text}</div>
      ))}
    </div>
  );
};

export default Main;

方式2:用connect(类组件或传统写法)

如果用connect高阶组件,需要定义MapStateToProps的类型,同时明确组件Props的结构:

// Main.tsx
import * as React from 'react';
import { connect, ConnectedProps } from 'react-redux';
import { State } from './App';
import Todo from '../models/Todo';

// 组件自身的Props(如果有的话)
interface OwnProps {
  // 比如自定义的回调、参数等
}

// 定义mapStateToProps,明确参数为State类型
const mapStateToProps = (state: State) => ({
  todoList: state.todoList,
  filterStatus: state.filterStatus,
  isAdding: state.isAdding,
});

// 生成连接后的完整Props类型
type Props = OwnProps & ConnectedProps<typeof connector>;

const connector = connect(mapStateToProps);

const Main = (props: Props) => {
  const { todoList, filterStatus, isAdding } = props;

  return (
    <div>
      <h2>Todo List</h2>
      {todoList.map(todo => (
        <div key={todo.id}>{todo.text}</div>
      ))}
    </div>
  );
};

export default connector(Main);

关键注意事项

  • 别忽略Action的类型:你现在的reducer里action用了any,这会丢失TypeScript的类型检查,建议定义Action类型:
    // 单独定义Action类型,放在types/index.ts里更方便全局引用
    type Action = 
      | { type: 'ADD_TODO'; payload: Todo }
      | { type: 'SET_FILTER'; payload: string }
      | { type: 'TOGGLE_ADDING' };
    
    const reducer = (state: State = defaultState, action: Action) => {
      switch(action.type) {
        case 'ADD_TODO':
          return { ...state, todoList: [...state.todoList, action.payload] };
        // 其他case逻辑
        default:
          return state;
      }
    };
    
  • State类型全局化:最好把State和Action类型单独放在一个文件(比如src/types/index.ts),而不是只在App.tsx里定义,这样其他组件导入更方便。
  • 拒绝any类型:尽量用明确的类型代替any,TypeScript才能帮你提前发现潜在错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:50:24