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

如何在Immer更新Draft时动态添加新属性?解决TypeScript TS7053类型报错问题

解决Immer Draft动态添加属性的TypeScript类型报错问题

这个问题在使用Immer结合TypeScript时很常见——你想给draft动态添加原类型里没有的属性,但TypeScript会因为类型不匹配抛出TS7053错误,同时你又不想修改MyObject本身的定义。下面是几种可行的解决方案:

方案1:直接使用交叉类型断言

把draft断言为原类型和新属性的交叉类型,明确告诉TypeScript这个draft现在包含你要添加的属性:

const payload = produce(data, (draft) => { 
  // 断言draft为包含newProperty的WritableDraft类型
  (draft as WritableDraft<MyObject & { newProperty: string }>)['newProperty'] = 'test';
});

这种方式简单直接,适合只添加单个明确属性的场景。

方案2:提前定义扩展类型

如果需要多次使用这个扩展后的类型,先单独定义出来会更清晰:

// 定义原类型和新属性的交叉类型
type MyObjectWithNewProp = MyObject & { newProperty: string };

const payload = produce(data, (draft) => { 
  (draft as WritableDraft<MyObjectWithNewProp>).newProperty = 'test';
});

这样代码可读性更高,后续如果要修改新属性的类型或添加更多属性,只需要修改MyObjectWithNewProp即可。

方案3:使用索引签名支持任意动态属性

如果需要添加多个不确定名称的动态属性,可以用Record类型给原类型加上索引签名:

const payload = produce(data, (draft) => { 
  // 允许添加任意字符串键的未知类型属性
  const typedDraft = draft as WritableDraft<MyObject & Record<string, unknown>>;
  typedDraft['newProperty'] = 'test';
  typedDraft['anotherDynamicProp'] = 123; // 也能添加其他属性
});

这个方案灵活性最高,适合属性名不固定或者需要批量添加属性的场景,但会失去对新属性的严格类型检查,需要根据实际需求选择。

为什么会报错?

Immer生成的draft类型是基于你传入的data的类型(MyObject)生成的WritableDraft<MyObject>,TypeScript会严格校验这个类型的属性,不允许添加原类型中未定义的属性。我们通过类型断言绕开了这个校验,同时不需要修改原MyObject的定义。

内容的提问来源于stack exchange,提问作者me.at.coding

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 08:47:45