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

Redux Toolkit+TypeScript赋值遇WritableDraft类型错误求助

Redux Toolkit + TypeScript 键赋值类型错误原因分析

核心问题拆解

  1. 数组元素类型写法错误
    你在AnimalToStateMap中定义的(LargeCatState, SmallCatState)[]是TypeScript的逗号表达式语法,并非联合类型数组。逗号表达式会取最后一个值作为结果,所以这个写法实际等价于SmallCatState[],完全不符合你想要的"包含两种动物状态的数组"的预期。正确的联合类型数组写法应该是(LargeCatState | SmallCatState)[]。

  2. 类型定义与实际需求不匹配

  • AllAnimalTpyes是AnimalToStateMap中所有值类型的联合,也就是各种单类型数组的组合(比如SmallCatState[] | SmallDogState[]),这个类型用于FooState.animals是合理的,因为animals本身就是数组。
  • 但你在queue的animal字段中错误使用了AllActivityTypes(推测是AllAnimalTpyes的笔误)——你实际要存储的是数组中取出的单个动物对象,而非数组本身,这里类型完全错位,直接导致类型不兼容。
  1. 类型不兼容引发的编译器推导混乱
    当你尝试将state.animals.at(index)返回的单个动物对象(类型为SmallCatState | SmallDogState | FishState | undefined)赋值给queue[id].animal时,由于queue.animal被错误定义为数组类型,TypeScript检测到严重的类型不匹配,进而抛出了看似奇怪的错误信息(编译器在处理联合类型数组和单个对象的冲突时,推导逻辑出现了混淆)。

为什么临时方法能"解决"问题

  • JSON.parse(JSON.stringify(animal))会将对象序列化为JSON再解析,这个过程会丢失TypeScript的类型信息,最终返回any类型,编译器会跳过类型检查,自然不会报错,但这是绕过类型系统的危险做法,会丢失类型安全。
  • //@ts-ignore是直接强制忽略当前行的类型错误,同样是放弃了类型检查,不推荐使用。

正确的修复方案

  1. 修正AnimalToStateMap的数组元素类型:
export interface AnimalToStateMap {
    [ANIMAL.cat]: (LargeCatState | SmallCatState)[],
    [ANIMAL.dog]: (LargeDogState | SmallDogState)[],
    [ANIMAL.fish]: (WhaleState | FishState)[]
}
  1. 定义单个动物的联合类型,用于queue字段:
// 从数组类型中提取元素类型
type AnimalElement<T> = T extends (infer U)[] ? U : never;
// 单个动物的联合类型
export type SingleAnimalType = AnimalElement<AnimalValues<AnimalToStateMap>>;
  1. 修正FooState的queue类型定义:
export interface FooState {
    animals: AllAnimalTpyes,
    queue: { [key: string]: { index: number, animal: SingleAnimalType } },
}

这样修改后,类型完全匹配,不需要绕过类型检查就能正常编译,同时保留了TypeScript的类型安全特性。

内容的提问来源于stack exchange,提问作者four-eyes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 02:57:43