如何在Immer + TypeScript中使用readonly数组?(v8版本兼容问题)
解决Immer 8+处理readonly数组的报错问题
Immer 8及以上版本对readonly类型的校验更严格,直接操作readonly数组会触发错误——这是因为readonly数组的设计初衷就是不可修改,而Immer的draft需要可写的引用。以下是几种可行的解决方法:
转换为普通数组后处理
用扩展运算符或Array.from()将readonly数组转为可写数组,再传入Immer的produce函数:const readonlyArr: readonly number[] = [1, 2, 3]; const newArr = produce([...readonlyArr], draft => { draft.push(4); });使用
castDraft显式标记(TypeScript场景)
Immer提供castDraft函数,可显式将readonly类型转为可修改的draft类型,绕过类型检查(仅在确认逻辑合理时使用,即你确实需要基于该readonly数组生成新的不可变状态):import { produce, castDraft } from "immer"; const readonlyArr: readonly number[] = [1, 2, 3]; const newArr = produce(castDraft(readonlyArr), draft => { draft.push(4); });调整状态定义逻辑
若状态由你维护,建议仅在对外暴露或持久化时设置为readonly,内部处理时保持为可写数组。这样既保证外部状态的不可变性,又不干扰Immer的正常工作。
Immer 8+的这个改动其实更贴合不可变状态的设计原则:readonly数组本就不应被直接修改,通过上述方式能明确区分原始不可变状态与可修改的draft,避免逻辑混淆。
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

