Redux Toolkit+TypeScript赋值遇WritableDraft类型错误求助
Redux Toolkit + TypeScript 键赋值类型错误原因分析
核心问题拆解
数组元素类型写法错误
你在AnimalToStateMap中定义的(LargeCatState, SmallCatState)[]是TypeScript的逗号表达式语法,并非联合类型数组。逗号表达式会取最后一个值作为结果,所以这个写法实际等价于SmallCatState[],完全不符合你想要的"包含两种动物状态的数组"的预期。正确的联合类型数组写法应该是(LargeCatState | SmallCatState)[]。类型定义与实际需求不匹配
AllAnimalTpyes是AnimalToStateMap中所有值类型的联合,也就是各种单类型数组的组合(比如SmallCatState[] | SmallDogState[]),这个类型用于FooState.animals是合理的,因为animals本身就是数组。- 但你在
queue的animal字段中错误使用了AllActivityTypes(推测是AllAnimalTpyes的笔误)——你实际要存储的是数组中取出的单个动物对象,而非数组本身,这里类型完全错位,直接导致类型不兼容。
- 类型不兼容引发的编译器推导混乱
当你尝试将state.animals.at(index)返回的单个动物对象(类型为SmallCatState | SmallDogState | FishState | undefined)赋值给queue[id].animal时,由于queue.animal被错误定义为数组类型,TypeScript检测到严重的类型不匹配,进而抛出了看似奇怪的错误信息(编译器在处理联合类型数组和单个对象的冲突时,推导逻辑出现了混淆)。
为什么临时方法能"解决"问题
JSON.parse(JSON.stringify(animal))会将对象序列化为JSON再解析,这个过程会丢失TypeScript的类型信息,最终返回any类型,编译器会跳过类型检查,自然不会报错,但这是绕过类型系统的危险做法,会丢失类型安全。//@ts-ignore是直接强制忽略当前行的类型错误,同样是放弃了类型检查,不推荐使用。
正确的修复方案
- 修正
AnimalToStateMap的数组元素类型:
export interface AnimalToStateMap { [ANIMAL.cat]: (LargeCatState | SmallCatState)[], [ANIMAL.dog]: (LargeDogState | SmallDogState)[], [ANIMAL.fish]: (WhaleState | FishState)[] }
- 定义单个动物的联合类型,用于
queue字段:
// 从数组类型中提取元素类型 type AnimalElement<T> = T extends (infer U)[] ? U : never; // 单个动物的联合类型 export type SingleAnimalType = AnimalElement<AnimalValues<AnimalToStateMap>>;
- 修正
FooState的queue类型定义:
export interface FooState { animals: AllAnimalTpyes, queue: { [key: string]: { index: number, animal: SingleAnimalType } }, }
这样修改后,类型完全匹配,不需要绕过类型检查就能正常编译,同时保留了TypeScript的类型安全特性。
内容的提问来源于stack exchange,提问作者four-eyes
相关产品推荐
相关产品推荐

