如何在TypeScript中声明空字典数组?React+Redux类型错误求助
React + Redux + TypeScript 任务管理器状态类型错误问题
我正在用React和Redux开发任务管理器来学习TypeScript,尝试将状态以字典数组的形式传递到Redux,但遇到了类型不匹配的错误,需要正确声明空字典数组的类型才能传递状态。
App.tsx 代码
import React, { FC, useState } from "react" import { useSelector, useDispatch } from "react-redux" import TodoList from "./Components/TodoList" import NameTodo from "./Components/NameTodo" import { RootState } from "./todoStore" import { createTodoCard } from "./todoReducer" interface TodoListTemplate { title: string, id: number, } const App: FC = () => { // Contains all the generated todo-lists const [generatedTodoList, setGeneratedTodoList] = useState<any[]>([]); const selector = useSelector((state: RootState) => { return state.todo }); const dispatch = useDispatch(); const generateTodoList = (): void => { // Sending this to the Redux state as an array of dictionaries const todoList: TodoListTemplate = { title: selector.todoCardName, id: Math.floor(Math.random() * 10000), } setGeneratedTodoList([...generatedTodoList, todoList]); // Reducer that would send todoList to the Redux state dispatch(createTodoCard(generatedTodoList)); } return ( ... ) } export default App
todoReducer.ts 代码
import { createAction, createReducer, PayloadAction } from '@reduxjs/toolkit' export const update = createAction<any[]>('update') export const toggleNaming = createAction<boolean>('toggleNaming') export const addTodoName = createAction<string>('addTodoName') //This is the reducer that would send the todoList to the array of dictionaries export const createTodoCard = createAction<Record<string, number>[]>('createTodoCard') export const todoReducer = createReducer( { todoList: [''], toggleNamingMenuState: false, todoCardName: '', // It should be sent here todoCard: [], }, (builder) => { builder .addCase(update, (state, action: PayloadAction<any[]>) => { state.todoList = action.payload }) .addCase(toggleNaming, (state, action: PayloadAction<boolean>) => { state.toggleNamingMenuState = action.payload }) .addCase(addTodoName, (state, action: PayloadAction<string>) => { state.todoCardName = action.payload }) .addCase(createTodoCard, (state, action: PayloadAction<Record<string, number>[]>) => { state.todoCard = action.payload }) } ) export default todoReducer
错误信息
Type 'Record<string, number>[]' is not assignable to type 'never[]'. Type 'Record<string, number>' is not assignable to type 'never'.
解决方案
问题根源
- Redux初始状态中
todoCard: []未指定类型,TypeScript自动推断为never[],导致后续赋值类型不匹配。 TodoListTemplate包含title(string类型)和id(number类型),但你用Record<string, number>定义action payload类型,这与实际数据结构不符(title的值是string,不是number)。
修复步骤
1. 统一TodoCard类型定义
在todoReducer.ts中定义与App.tsx一致的类型,确保全项目类型统一:
import { createAction, createReducer, PayloadAction } from '@reduxjs/toolkit' // 定义统一的TodoCard类型 export interface TodoCard { title: string; id: number; } // ... 其他action定义
2. 给Redux初始状态指定类型
修改todoReducer.ts中的初始状态,给todoCard明确类型:
export const todoReducer = createReducer( { todoList: [''], toggleNamingMenuState: false, todoCardName: '', // 指定为TodoCard数组,初始为空 todoCard: [] as TodoCard[], }, (builder) => { // ... 原有builder逻辑 .addCase(createTodoCard, (state, action: PayloadAction<TodoCard[]>) => { state.todoCard = action.payload }) } )
3. 修正createTodoCard的payload类型
将action的payload类型改为TodoCard[]:
export const createTodoCard = createAction<TodoCard[]>('createTodoCard')
4. 优化App.tsx中的useState类型
替换any[]为TodoCard[],避免使用any:
import { TodoCard } from "./todoReducer"; // ... const [generatedTodoList, setGeneratedTodoList] = useState<TodoCard[]>([]);
5. (可选)去掉重复状态管理
你当前同时用组件内state和Redux存储相同数据,建议直接操作Redux状态,减少冗余:
const generateTodoList = (): void => { const newTodoCard: TodoCard = { title: selector.todoCardName, id: Math.floor(Math.random() * 10000), } // 基于Redux现有状态更新 dispatch(createTodoCard([...selector.todoCard, newTodoCard])); }
这样就能彻底解决类型不匹配的问题,同时让状态管理更规范。
内容的提问来源于stack exchange,提问作者lgab1219
相关产品推荐
相关产品推荐

