求ESLint规则:检测未调用Logger.log返回的绑定函数
用ESLint检测Logger.log返回函数未调用的问题
问题说明
我实现了一个Logger类,通过console.log.bind(console, ...args)确保浏览器控制台显示正确的源文件行号(而非Logger类的固定行号)。但这个设计要求必须调用Logger.log()返回的函数才会输出日志,我经常遗漏这一步导致无日志输出,想通过ESLint规则检测这类错误调用。
核心代码示例:
class Logger { log(...args: any[]) { // 预处理日志参数 return console.log.bind(console, ...args); } } // ✅ 正确调用:需二次调用返回的函数 Logger.log("some text")(); // ❌ 错误调用:无日志输出 Logger.log("some text");
解决方案
1. 自定义ESLint规则
可以编写自定义规则专门检测这类场景,精准识别Logger.log调用后未执行返回函数的情况。
示例规则代码(简化版):
module.exports = { create(context) { return { CallExpression(node) { // 匹配Logger.log的调用表达式 const isLoggerLogCall = node.callee.type === 'MemberExpression' && node.callee.object.name === 'Logger' && node.callee.property.name === 'log'; if (isLoggerLogCall) { // 检查当前调用是否被外层CallExpression包裹(即是否被执行) const isCalled = context.getAncestors().some(ancestor => ancestor.type === 'CallExpression' && ancestor.callee === node ); if (!isCalled) { context.report({ node, message: '必须调用Logger.log返回的函数才能输出日志' }); } } } }; } };
2. 复用现有ESLint规则(快速方案)
无需自定义规则的话,可以用@typescript-eslint/no-unused-expressions规则,它会检测未被使用的表达式——Logger.log("some text")返回的函数未被调用时,属于未使用的表达式,会被该规则捕获。
在ESLint配置中启用并调整规则:
{ "rules": { "@typescript-eslint/no-unused-expressions": [ "warn", { "allowShortCircuit": true, "allowTernary": true } ] } }
注意:如果代码中有其他合法的未使用表达式(比如某些副作用表达式),可能需要通过注释// eslint-disable-next-line @typescript-eslint/no-unused-expressions添加例外。
可选优化:修改Logger设计避免二次调用
如果想从根源上避免忘记调用,可以调整Logger的实现,但要注意不能破坏行号显示:
- 可以尝试利用
Error对象获取调用栈,手动修正行号,但复杂度较高; - 或者在开发环境下给返回的函数添加一个自定义标识,结合ESLint规则强制调用,但不如直接检测未调用的方式直接。
内容的提问来源于stack exchange,提问作者mikhail-koviazin
相关产品推荐
相关产品推荐

