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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 16:13:14