DEBUG.WIKI
IPPeak:从目标地区访问网页,住宅代理、SEO 监测、广告验证
RackNerd;$21.99/年 · 1GB KVM
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →

es-toolkit 合并同类型对象,返回值却不兼容原类型

升级 es-toolkit 1.52.0 后,merge 返回类型可能错误展开字符串交叉类型或数组联合。对照 1.53.0 的 Merge 类型修正,保留真正的运行时合并规则。

两个对象声明成相同的配置类型,升级 es-toolkit 1.52.0 后,merge() 的返回值却不能再赋给原类型。错误中可能突然出现 length、toString 等字符串成员,或者混合了原本分开的数组形状。

如果配置类型包含 string & {},或 string[] | string[][] 一类联合,应检查 1.52.0 新增的深合并返回类型。它与“运行时返回的对象一定坏了”不是同一个结论。

同类型输入也被递归拆开了

下面是只用于类型检查的最小示例,declare 变量不提供运行时值:

import { merge } from 'es-toolkit';

declare const textOptions: { value: string & {} };
declare const arrayOptions: { value: string[] | string[][] };

merge(textOptions, textOptions) satisfies typeof textOptions;
merge(arrayOptions, arrayOptions) satisfies typeof arrayOptions;

1.52.0 的 Merge 条件类型会递归分析对象和数组。字符串与空对象类型的交叉,在类型判断中可能走进 object 分支,进而展开 String 的成员;不同数组联合成员之间的组合,也可能产生原配置不接受的混合数组类型。

不要因此把业务允许的字符串改成对象,或删除合法的数组联合。先判断是这个版本的声明推导回归,还是输入的两份配置本来就可能合并成接口不接受的值。

正式 1.53.0 调整了相同类型与原始类型判断

正式 es-toolkit 1.53.0 的 Merge 会在输入类型相等时保留该类型,并显式排除原始类型进入普通对象递归。发布说明也包含同类型合并与更窄输入类型的修正。

符合上述场景时,可沿现有依赖流程采用 1.53.0,核对项目实际解析的声明文件,然后重新检查原来的赋值位置。不要只在编辑器里重启一次语言服务,就认定构建产物已经使用新包。

as any 会同时掩盖真正的不兼容配置,不能作为默认修复。用 toMerged 替代 merge 也不是单纯换一个类型签名:merge 会原地修改 target,而 toMerged 的用途是生成合并结果,已有对象身份和修改时机可能因此变化。

类型修复没有改变数组按索引合并的契约

merge 会递归合并嵌套对象与数组,数组不是默认整段替换。例如目标 [1, 2] 与来源 [3] 合并,可能保留第二个目标元素。业务如果希望“来源数组完全替换”,本来就需要另一份明确策略,不能指望返回类型更新顺便改变运行时行为。

同样,来源可能是 undefined、两边实际类型不同,或同一字段可在对象与数组之间变化时,结果类型不保证等于某一侧。1.53.0 保留相同类型,不意味着所有 merge 结果都可以强制标成 target 类型。

验收应回到原配置调用:确认类型检查不再错误展开字符串成员,同时核对嵌套数组、undefined 来源字段、目标对象是否被原地修改,以及最终配置消费者是否接受结果。类型检查通过只能证明静态约束满足,不能替代这几项运行时语义检查。