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

如何在TypeScript中用Immer转换不同泛型参数的Data类型?

问题:使用Immer安全转换泛型Immutable类型的类型参数

类型定义与需求

首先有如下类型定义:

type Data<T> = Immutable<{ data: T }>
const a: Data<number> = { data: 0 }

需要用immer的produce函数,将变量a从Data<number>类型转换为Data<string>类型。

直接调用的类型错误

尝试直接调用produce会触发类型报错:

produce(a, (d) => { d.data = d.data.toString() })

报错信息:Type 'string' is not assignable to type 'number',原因是回调中试图给Data<number>的data字段赋值字符串,类型不匹配。

不符合类型安全的“合法”写法

但下面这段代码却能通过TypeScript的类型检查,这明显不合理:

produce<Data<number>, Draft<Data<string>>>(a, (d) => { d.data = d.data.toString() }) // 结果类型:Data<number>

问题在于:

  • 返回值的类型被推断为Data<number>,但实际data字段已经被修改为字符串,类型和实际值完全不符
  • 回调参数d的data字段被错误识别为string类型,和原始值的number类型矛盾,完全违背了类型安全的原则

当前可行但不严谨的方案

目前找到的可行写法是用any做类型断言:

produce<Data<string>>(a as any, (d) => { d.data = d.data.toString() })

需要注意:TypeScript会把回调里的d.data识别为string类型,但实际上原始值是number,这段代码能运行只是因为toString()方法在number和string类型上都存在,属于偶然可行的情况,并不严谨。

疑问

请问在TypeScript中,有没有更合理、真正符合类型安全的实现方式?

内容的提问来源于stack exchange,提问作者Aleksandar Dimitrov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 16:57:30