ESLint 修复后问号报错:三元条件被误当成回调
ESLint 10.11.0 的 prefer-arrow-callback 会把三元条件中的函数修成无效箭头语法。10.12.0 已修正误判,更新工具后仍须恢复已经写入的错误 diff。
原代码可以解析,启用 prefer-arrow-callback 自动修复后,却在问号处报 Parsing error: Unexpected token ?。若函数表达式位于三元表达式的条件位置,要先检查规则是否把它误当成了传给调用方的回调。
ESLint 10.11.0 的明确触发形式是 foo(function() {} ? a : b)。正式 10.12.0 修正了这条回调判定,10.13.0 也保留了修正。问题的关键不只是给箭头函数补括号:这个条件位置的函数本来就不是调用参数的最终值。
条件函数不会作为三元结果传出去
错误改写可由下面两行看出:
// 原输入
foo(function() {} ? a : b);
// 受影响修复器可能写出的无效结果
foo(() => {} ? a : b);
原输入先判断函数对象的真假,再把 a 或 b 传给 foo;函数表达式本身并没有作为回调传入。旧规则向上遍历三元表达式时,没有区分 test、consequent 与 alternate,因而在 test 上报告并尝试转换。
函数位于真正的结果分支时,情况不同,例如 foo(flag ? function() {} : other) 可能确实把函数作为参数。不能为了这一处误报,认定所有三元表达式中的回调都应被忽略。
恢复无效改动,再更新回调判定
先对照自动修复的 diff,只撤回这次生成的无效语法,保留同一文件里其他已确认的编辑。若编辑器保存仍会再次运行旧修复器,应先限制该文件的自动写入,再恢复代码。
项目允许时,采用包含修正的 ESLint 10.12.0 或兼容的后续正式版本,并确认编辑器、命令行与 CI 实际解析的是同一份工具。修正后的规则遇到三元 test 会停止把它当成回调继续上溯;它没有禁止真正结果分支中的回调检查。
短期不能更新时,可以在这处保留明确的局部规则豁免,由人工审查表达式。不要全局关闭 lint,也不要只给错误输出补括号后就宣称规则判断正确。若决定进一步简化原有恒真条件,那是另一项代码行为审查,需同时考虑表达式求值与项目意图,不应混在机械修复中完成。
这个回归也可能出现在构造调用、嵌套三元表达式或带 .bind(this) 的函数形态中。验收应检查自动修复后的文件能够解析,test 位置不再被这条规则误报,真正用作回调的结果分支仍按配置处理,再运行原有行为检查。
更新工具不会自动撤销已经保存或提交的错误 diff。恢复语法与更新修复器需要分别完成;只看到 lint 本轮退出成功,不能证明旧产物已被替换。


