在Redux中使用TypeScript类型定义时遇到WritableDraft错误
TypeScript类型错误解决:联合类型数组与对应属性数组的类型匹配问题
错误原因
TypeScript无法建立animalKey与对应动物类型的关联关系。当animalKey的类型是keyof Required<Foo>['animals'](即'dogs'|'cats'|'fishs')时,state.animals[animalKey]的类型会被推断为Dogs[] | Cats[] | Fishs[],而animal是Dogs|Cats|Fishs的联合类型。此时TypeScript会要求animal必须满足所有数组元素类型的交集(Dogs & Cats & Fishs),这显然无法实现,因此抛出类型不兼容错误。
解决方案
方案1:泛型关联Key与动物类型
通过泛型约束animalKey,让TypeScript明确知道当前key对应的动物类型,从而正确推断数组元素类型:
type AnimalMap = Required<Foo>['animals'] someFunction: <K extends keyof AnimalMap>( state, action: PayloadAction<{ index: number, animalKey: K }> ) => { const { index, animalKey } = action.payload // 断言animal为当前key对应的动物类型 const animal = state.animalQueue[index] as AnimalMap[K][number] state.animals[animalKey]!.push(animal) }
方案2:类型守卫判断(繁琐但更安全)
如果需要严格的类型检查,可以定义类型守卫函数,手动判断animal的类型是否与animalKey匹配:
// 定义类型守卫函数,假设Dogs/Cats/Fishs有各自独有的属性 function isDog(animal: Dogs | Cats | Fishs): animal is Dogs { return 'breed' in animal } function isCat(animal: Dogs | Cats | Fishs): animal is Cats { return 'height' in animal } function isFish(animal: Dogs | Cats | Fishs): animal is Fishs { return 'waterType' in animal } someFunction: (state, action: PayloadAction<{ index: number, animalKey: keyof Required<Foo>['animals']}>) => { const { index, animalKey } = action.payload const animal = state.animalQueue[index] if (animalKey === 'dogs' && isDog(animal)) { state.animals.dogs!.push(animal) } else if (animalKey === 'cats' && isCat(animal)) { state.animals.cats!.push(animal) } else if (animalKey === 'fishs' && isFish(animal)) { state.animals.fishs!.push(animal) } }
说明
你的animalQueue定义(Dogs | Cats | Fishs)[]本身是没问题的,它确实表示可以包含任意数量这三种类型元素的数组。问题出在TypeScript无法自动关联animalKey和对应的动物类型,需要通过泛型或类型守卫来明确这种关联。
内容的提问来源于stack exchange,提问作者four-eyes
相关产品推荐
相关产品推荐

