新闻详情

新闻详情

首页 / 资讯中心 / 详情

深入解析 eslint-plugin-unicorn 的 require-proxy-trap-boolean-return 规则:让 Proxy 陷阱返回真正的布尔值

发布时间:2026/9/18 3:12:13来源:尧图网络
深入解析 eslint-plugin-unicorn 的 require-proxy-trap-boolean-return 规则:让 Proxy 陷阱返回真正的布尔值
深入解析 eslint-plugin-unicorn 的 require-proxy-trap-boolean-return 规则让 Proxy 陷阱返回真正的布尔值【免费下载链接】eslint-plugin-unicornMore than 300 powerful ESLint rules项目地址: https://gitcode.com/GitHub_Trending/es/eslint-plugin-unicorn本文围绕 eslint-plugin-unicorn 中的require-proxy-trap-boolean-return规则展开说明它为什么要求set、deleteProperty等 Proxy 陷阱必须返回布尔值、在哪些场景下可以豁免以及该规则的自动修复能力与底层实现原理。读完本文你将能独立配置并使用这条规则理解它如何利用 ESLint 代码路径分析识别必然退出的函数体并在自己的代码中写出既符合规范又可自动修复的 Proxy 处理器。规则背景为什么 Proxy 陷阱必须返回布尔值JavaScript 的Proxy允许拦截对象的底层操作其中一部分陷阱trap在 ECMAScript 规范中被明确要求返回一个布尔值结果。若陷阱函数因忘记return而返回undefined在许多常见操作如set、deleteProperty中会直接抛出TypeError若返回其他 truthy/falsy 值则依赖隐式类型转换语义不清晰容易埋下难以排查的隐患。本规则源码在 rules/require-proxy-trap-boolean-return.js 中用一个集合列出了全部 7 个布尔陷阱陷阱名称触发时机规范要求的语义set赋值obj[key] value是否写入成功deletePropertydelete obj[key]属性是否被删除definePropertyObject.defineProperty(obj, key, desc)属性是否定义成功haskey in obj属性是否存在isExtensibleObject.isExtensible(obj)对象是否可扩展preventExtensionsObject.preventExtensions(obj)是否成功阻止扩展setPrototypeOfObject.setPrototypeOf(obj, proto)原型是否设置成功该规则只检查内联对象字面量形式的处理器即直接写在new Proxy()或Proxy.revocable()第二个参数中的 handler对应源码中的isProxyConstructorCall与isProxyRevocableCall判断见 rules/require-proxy-trap-boolean-return.js通过变量引用传入的 handler 不在检查范围内。规则启用方式根据 readme.md 中的规则总表require-proxy-trap-boolean-return同时被标记为 ✅recommended和 ☑️unopinionated且支持 自动修复--fix。也就是说使用项目推荐配置的用户无需手动开启即可生效。若需要单独启用可在 ESLint 的 flat config 中配置import eslintPluginUnicorn from eslint-plugin-unicorn; export default [ { plugins: { unicorn: eslintPluginUnicorn, }, rules: { unicorn/require-proxy-trap-boolean-return: error, }, }, ];该规则在 ESLint 侧的元数据为type: problem、fixable: code仅支持js/js语言相关定义见 rules/require-proxy-trap-boolean-return.js。正确与错误用法示例规则文档 docs/rules/require-proxy-trap-boolean-return.md 给出了三类典型示例以下完整继承并补充测试中的更多情形。1. 忘记return显式补上true// ❌ 错误set 陷阱忘记返回布尔值 new Proxy(target, { set(target, property, value) { target[property] value; } }); // ✅ 正确 new Proxy(target, { set(target, property, value) { target[property] value; return true; } });2. 返回非布尔值依赖隐式转换// ❌ 错误返回数字 1 依赖隐式转换 new Proxy(target, { deleteProperty() { return 1; } }); // ✅ 正确 new Proxy(target, { deleteProperty() { return true; } });3. 推荐写法委托给 Reflect// ✅ 正确直接转发给 Reflect 方法天然返回布尔值 new Proxy(target, { set(target, property, value) { return Reflect.set(target, property, value); } });除此之外测试用例 还覆盖了大量同类情形例如// ❌ 错误显式 return; 等价于返回 undefined new Proxy(target, {set(target, property, value) { return; }}); // ❌ 错误has 陷阱返回字符串 new Proxy(target, {has() { return yes; }}); // ✅ 修复后new Proxy(target, {has() { return true; }}); // ✅ 正确deleteProperty 直接使用 delete 运算符 new Proxy(target, {deleteProperty(target, property) { return delete target[property]; }});豁免场景必然退出的陷阱无需返回布尔值规则文档明确指出一个始终抛出异常、无限循环、或调用全局process.exit()的陷阱不需要返回布尔值——因为它的执行流根本不会正常返回也就不存在返回undefined或隐式转换的问题。以下写法均被视为有效测试中均为valid用例// 始终抛错 new Proxy(target, {set() { throw new Error(); }}); // 无限循环 new Proxy(target, {set() { while (true) { doSomething(); } }}); // 调用 process.exit() new Proxy(target, {set() { process.exit(1); }}); // if/else 两个分支都返回布尔值 new Proxy(target, {set() { if (condition) { return true; } else { return false; } }});同时只要任何一个执行路径可能自然流出函数体规则就会报告。例如以下用例在测试中都被判为无效// 只有 if 分支退出没有 else函数可能自然流出 new Proxy(target, {preventExtensions() { if (condition) { throw new Error(); } doSomething(); }}); // switch 缺少 default可能穿透流出 new Proxy(target, {preventExtensions() { switch (value) { case 1: return true; } }}); // 嵌套函数中的 return 不会让外层陷阱满足要求 new Proxy(target, {preventExtensions() { const compute () true; if (compute()) { return true; } }});自动修复把可静态确定的非布尔值替换为布尔字面量该规则支持--fix自动修复但其修复能力是有选择性的只有当一个返回表达式可以被静态确定为非布尔值、且替换后不产生副作用时才会自动改写。核心逻辑在getBooleanReplacementrules/require-proxy-trap-boolean-return.js可以修复普通字面量Literal排除正则、不含表达式的模板字符串、标识符undefined直接替换为对应的布尔字面量不修复表达式内包含注释getCommentsInside非空、无法静态求值的表达式以及被归类为已知非布尔表达式的节点类型。测试中的修复示例invalid用例带output字段可直观看到修复效果原始代码修复后输出new Proxy(target, {set() { return 1; }})new Proxy(target, {set() { return true; }})new Proxy(target, {deleteProperty: () 0})new Proxy(target, {deleteProperty: () false})new Proxy(target, {defineProperty() { return ; }})new Proxy(target, {defineProperty() { return false; }})new Proxy(target, {has() { return yes; }})new Proxy(target, {has() { return true; }})new Proxy(target, {isExtensible() { return undefined; }})new Proxy(target, {isExtensible() { return false; }})new Proxy(target, {isExtensible() { return condition ? true : 1; }})new Proxy(target, {isExtensible() { return condition ? true : true; }})其中最后一个例子说明对于三元表达式规则会分别检查两个分支仅把非布尔的分支替换掉。此外Proxy.revocable同样支持修复Proxy.revocable(target, {set() { return 1; }})会被修复为Proxy.revocable(target, {set() { return true; }})。对于无法安全修复的场景例如返回数组、函数、对象、new Boolean(true)、value 1等规则只报告Proxy trap \{{name}} should return a boolean. 错误而不提供修复需要开发者手动改写。规则实现原理源码级拆解从源码结构看该规则大致由四个层次构成理解这些有助于判断规则在各种边界情况下的行为。1. 识别目标陷阱函数getTrapFunctionrules/require-proxy-trap-boolean-return.js要求满足全部条件才会认定为目标节点handler 属性必须是Property且kind为init排除 getter/setter 形式如{get set() {}}不检查属性名含计算属性名如[set]解析后必须属于上述 7 个布尔陷阱之一属性值必须是函数类型箭头函数、函数声明或函数表达式集合定义见functionTypesrules/require-proxy-trap-boolean-return.js。isProxyTrapFunction再向上回溯确认属性 → handler 对象 → Proxy 调用的层级关系确保只命中new Proxy()/Proxy.revocable()的内联字面量 handler。2. 遍历返回语句并做静态求值getReturnStatementsrules/require-proxy-trap-boolean-return.js递归收集函数体内的所有ReturnStatement但不会穿透嵌套函数——这正是嵌套函数里的return不算数这一行为的来源。对每个返回表达式getStaticBooleanValuerules/require-proxy-trap-boolean-return.js基于eslint-community/eslint-utils的getStaticValue做静态求值先解包 TypeScript 表达式unwrapTypeScriptExpression若值可静态确定且不是布尔类型则给出对应的布尔结果若表达式可能涉及可变成员访问或带副作用的常量初始化器则放弃推断。在此基础上规则还维护了两张已知非布尔清单knownNonBooleanExpressionTypes数组、箭头函数、类、函数、new、对象、模板字符串、更新表达式等见 rules/require-proxy-trap-boolean-return.jsnonBooleanBinaryOperators%、、*、**、、-、/、移位、^、|等数值运算符见 rules/require-proxy-trap-boolean-return.js。凡是命中这两类清单的表达式如return value 1、return typeof value、return${value}都直接报告错误。而、、instanceof、in等比较/逻辑类表达式天然产生布尔值测试中均被列为有效用例。getProblem还会递归解包AssignmentExpression仅、ConditionalExpression、LogicalExpression、SequenceExpression等复合表达式逐层定位真正产出值的那个子表达式以决定是否可以修复。3. 代码路径分析判断函数体是否必然退出这是该规则最精巧的部分。为了准确实现始终 throw / 死循环 / process.exit() 可豁免的语义规则借助 ESLint 的 Code Path Analysis 事件onCodePathStart、onCodePathSegmentStart/End、onUnreachableCodePathSegmentStart/End见 rules/require-proxy-trap-boolean-return.js跟踪每个 trap 函数体内的代码段可达性构建出functionBodyAlwaysExits这个WeakMap。在BlockStatement退出时此时代码段尚未结束可达性信息仍然有效规则通过两个条件判断函数体是否必然退出所有代码段均不可达isAllUnreachable对应死循环等场景或存在简单出口isBranchExit所有路径都是return/throw或isProcessExitBranch所有路径都调用process.exit()。测试中有大量用例专门验证这一机制例如// 有效while (true) 死循环 new Proxy(target, {set() { while (true) { doSomething(); } }}); // 有效for (;;) 死循环 new Proxy(target, {set() { for (;;) { doSomething(); } }}); // 有效try/catch 两个分支都退出 new Proxy(target, {set() { try { return doSomething(); } catch { throw new Error(); } }}); // 有效if/else 每个分支都返回 new Proxy(target, {set() { if (a) { if (b) { return true; } else { return false; } } else { return true; } }}); // 无效标签 break 只退出标签语句函数仍可能流出 new Proxy(target, {preventExtensions() { label: { break label; } }});4. 特殊形态async 与 generator 陷阱无论其内部是否有returnasync陷阱和 generator 陷阱都会被直接报告rules/require-proxy-trap-boolean-return.js。这是因为 async 函数返回值会被包装成 Promise、generator 返回的是迭代器对象都无法满足规范要求的同步布尔返回值。对应测试用例// 均判为无效 new Proxy(target, {setPrototypeOf: async () true}); new Proxy(target, {* setPrototypeOf() { return true; }});与测试用例的相互印证test/require-proxy-trap-boolean-return.js 为每条行为分支提供了详尽的验证valid 部分覆盖Reflect转发、delete运算符、比较/逻辑表达式、throw、各类死循环、各种形态的process.exit()含try/finally、switch、可选链、序列表达式、class static 块中等上下文、if/else与穷尽switch的完整返回、箭头函数简写体、计算属性名陷阱、getter 形式属性{get set() {}}不误报以及非布尔陷阱get、apply不受影响invalid 部分覆盖无返回、空return、数字/字符串/对象/数组/函数等非布尔返回值、非穷尽switch、缺少 else 的 if、嵌套函数返回、async/generator 陷阱、带副作用的序列与复合表达式等并给出可验证的output修复结果。使用建议与边界说明优先使用Reflect转发Reflect.set、Reflect.deleteProperty、Reflect.defineProperty等方法直接返回规范要求的布尔值既能满足本规则又能保证与目标对象原生行为的语义一致是文档与测试中反复出现的最稳妥写法。善用自动修复对于return 1、return 、return undefined这类静态值--fix会直接改写为布尔字面量但对涉及副作用或无法静态求值的表达式请手动确认语义后再修改。理解检查边界本规则只检查内联对象字面量 handler。若把 handler 定义为变量再传入new Proxy(target, handler)将不会被本规则检查对这种写法规则文档与源码目前都未提供进一步的追踪能力。豁免不等于可省略必然退出的豁免仅适用于确定无法正常返回的函数体只要存在一条路径可能流出函数规则就会要求补上布尔返回值。如需查阅规则在总表中的位置、完整导出与推荐配置可继续查看 readme.md、规则出口 与 flat 配置基座规则文档本身位于 docs/rules/require-proxy-trap-boolean-return.md。【免费下载链接】eslint-plugin-unicornMore than 300 powerful ESLint rules项目地址: https://gitcode.com/GitHub_Trending/es/eslint-plugin-unicorn创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

单片机毕设选题推荐:基于 STM32 或 51 单片机的水位传感尿床报警硬件系统设计 基于 STM32 或 51 单片机的 4G 远程提醒婴儿智能监护仪设计(025407) 2026/9/18 3:12:13

单片机毕设选题推荐:基于 STM32 或 51 单片机的水位传感尿床报警硬件系统设计 基于 STM32 或 51 单片机的 4G 远程提醒婴儿智能监护仪设计(025407)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️…

阅读更多 →
单片机毕设选题推荐:基于 STM32 或 51 单片机的声光告警式智能饮水装置实现 基于 STM32 或 51 单片机的 PTC 加热恒温智能水杯系统设计(025307) 2026/9/18 3:12:13

单片机毕设选题推荐:基于 STM32 或 51 单片机的声光告警式智能饮水装置实现 基于 STM32 或 51 单片机的 PTC 加热恒温智能水杯系统设计(025307)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️…

阅读更多 →
splitk:从交互探索到规则固化,打造日志解析的确定性工作流 2026/9/18 3:09:12

splitk:从交互探索到规则固化,打造日志解析的确定性工作流

前阵子我处理一批客户环境导出的服务日志,格式和文档里写的完全不是一个东西。用 awk 和 cut 的组合拳试到第三轮,才终于把 IP 和状态码抽出来,结果时间字段又带了个毫秒尾巴,整条命令还得接着改。身边同事贴过来看了一眼说&#…

阅读更多 →

最新相关资讯

2026年AI论文工具排行榜TOP5:从功能到价格全面对比,okbiye凭什么稳居榜首 2026/9/18 4:36:22

2026年AI论文工具排行榜TOP5:从功能到价格全面对比,okbiye凭什么稳居榜首

2026年的毕设,AI论文工具已经成了刚需。但市面上的工具鱼龙混杂,从通用大模型到各种号称"论文写作神器"的小工具,少说也有几十款。很多同学不知道该怎么选,看了一堆测评还是一头雾水,随便选一个用了才发现各…

阅读更多 →
CXL.mem Back-Invalidate机制深度解析:从缓存一致性到分布式协调 2026/9/18 4:36:22

CXL.mem Back-Invalidate机制深度解析:从缓存一致性到分布式协调

我最初接触CXL 3.0时,最大的困惑不是带宽翻倍或交换拓扑,而是CXL.mem协议里那个"反直觉"的方向问题。CPU访问CXL内存时,缓存一致性是主机说了算,这很好理解。可当CXL内存设备反过来要清掉CPU缓存里的旧副本时&#xff0…

阅读更多 →
Anaconda 安装教程:从下载到换源,新手零踩坑 2026/9/18 4:36:22

Anaconda 安装教程:从下载到换源,新手零踩坑

本文首发于 CSDN,转载请注明出处。 Anaconda 一次装齐 Python 加上几百个数据科学常用库,还自带 conda 环境管理,是很多人装 Python 的第一选择。但它的安装选项里藏着两个容易踩的坑:一个勾错了会污染系统 PATH,还有一…

阅读更多 →
dlt 官方文档工程全指南:从本地环境搭建到 Docusaurus 站点构建、多版本与 LLM 友好输出 2026/9/18 4:36:22

dlt 官方文档工程全指南:从本地环境搭建到 Docusaurus 站点构建、多版本与 LLM 友好输出

dlt 官方文档工程全指南:从本地环境搭建到 Docusaurus 站点构建、多版本与 LLM 友好输出 【免费下载链接】dlt data load tool (dlt) is an open source Python library that makes data loading easy 🛠️ 项目地址: https://gitcode.com/GitHub_Tre…

阅读更多 →
青龙面板Docker部署与依赖管理:定时任务脚本自动化实战 2026/9/18 4:36:22

青龙面板Docker部署与依赖管理:定时任务脚本自动化实战

青龙面板这东西,最早一批折腾它的人多半是为了把那些"每天到点就得手动点一下"的琐碎操作托管出去,后来用着用着发现它其实就是一个带界面、带日志、带定时调度的脚本运行环境。这次聊的是青龙配上快手极速版这类日常任务脚本的完整使用链路—…

阅读更多 →
告别PPT模板感:用InDesign打造电影级交互式PDF演示文档 2026/9/18 4:33:22

告别PPT模板感:用InDesign打造电影级交互式PDF演示文档

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞