ESLint 把 typeof 的双等号修成全等后,判断变了
ESLint 10.13.0 的 eqeqeq 自动修复可能仅因一侧是 typeof 就替换运算符,另一侧为对象时会改变强制转换语义。保留规则报告,限制自动写入并人工确认比较契约。
只运行一次 ESLint 自动修复,代码仍能解析,原来为 true 的类型判断却变成 false。如果 diff 只是把 typeof value == expected 改成三个等号,应检查 expected 是否真的是字符串。
ESLint 10.13.0 的 eqeqeq 会把一侧包含 typeof 的比较当作可直接自动修复的路径。typeof 的结果确实是字符串,但另一侧不一定也是字符串;对象参与宽松比较时可能发生转换,换成全等会改变结果。
另一侧是对象时,改运算符会改变语义
下面展示两种比较的区别:
const value = 42;
const expected = { toString: () => 'number' };
console.log(typeof value == expected); // true
console.log(typeof value === expected); // false
第一种比较会对对象执行相应的原始值转换,第二种则直接比较不同类型,不会得到同样结果。这不表示业务应该刻意使用这种写法,只说明自动改成全等之前,不能仅凭一侧是 typeof 就证明语义不变。
先检查修复前的实际操作数类型和调用约定。若本来就要求字符串,却意外传入对象,可能需要修正的是调用方;若对象转换是已有接口的一部分,则需要明确保留或迁移这个契约。
不要把另一侧统一包成 String(expected) 后批量替换。显式字符串转换与宽松比较涉及的原始值转换提示并不总是相同,带自定义转换方法的对象尤其需要单独检查。
保留检查,限制自动写入
发现已经写入的错误改动时,先逐项对照 diff 恢复该比较,保留文件中其他已确认的编辑。编辑器保存会再次运行修复的话,也应先限制这条写入路径,避免刚恢复又被改回去。
使用 ESLint 的 Node API 驱动修复时,可以过滤这条规则的自动修改,同时继续得到它的诊断:
import { ESLint } from 'eslint';
const eslint = new ESLint({
fix: (message) => message.ruleId !== 'eqeqeq',
});
这是构造已有 lint 流程的局部配置,需要保留原配置加载、文件选择和结果处理。它暂时排除所有 eqeqeq 的自动修复,而不只这一种 typeof 形状;其余提示仍应人工处理。
只用 CLI 时,可先运行不带 --fix 的检查并审查修改建议,或在独立分支使用不会直接覆盖源文件的检查流程。把规则从 error 改成 warn 并不会天然禁止自动修复,也不要为了这一条缺口全局关闭 lint。
能解析,还要比较行为
回归应包含另一侧为预期字符串、对象及非法输入的路径,确认比较结果和错误处理符合业务契约。再检查工具实际写出的 diff,避免只看到 lint 退出成功就接受所有修改。
这条问题针对 typeof 比较的自动修复条件,不表示所有 == 都应保留,也不代表所有 eqeqeq 提示都错误。采用后续规则版本时,继续用相同操作数形状验证,再决定是否恢复自动修复;已经落盘的旧 diff 仍需要单独审查。


