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

如何在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'.

解决方案

问题根源

  1. Redux初始状态中todoCard: []未指定类型,TypeScript自动推断为never[],导致后续赋值类型不匹配。
  2. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 15:45:23