资讯动态

eslint-plugin-unicorn no-typeof-undefined 规则测试快照解读:27 个边界用例如何验证 typeof 到 undefined 的自动修复

发布时间:2026/9/18 23:53:44 来源:尧图企业网站定制
eslint-plugin-unicorn no-typeof-undefined 规则测试快照解读27 个边界用例如何验证 typeof 到 undefined 的自动修复【免费下载链接】eslint-plugin-unicornMore than 300 powerful ESLint rules项目地址: https://gitcode.com/GitHub_Trending/es/eslint-plugin-unicorn本文以 no-typeof-undefined 规则的 AVA 快照报告为核心完整拆解该规则 27 个无效用例的输入/输出快照并结合 规则源码、测试用例 与 规则文档 说明修复器的行为边界宽松等号升级、ASI 保护、return 换行加括号、全局变量的 suggestion 降级等细节帮助读者准确理解并正确配置这条可自动修复的规则。快照报告是什么结构与数据来源test/snapshots/no-typeof-undefined.js.md 是 test/no-typeof-undefined.js 这份测试文件运行后由 AVA 测试框架生成的快照报告snapshot report真实的二进制快照数据保存在同目录下的 no-typeof-undefined.js.snap 中报告本身则是其人类可读的渲染结果由 test/utils/snapshot-rule-tester.js 中的快照逻辑负责序列化。报告由两组invalid区块构成第一组invalid(1)~invalid(23)使用默认选项运行的 23 个用例每个用例展示 Input输入代码、Error报错信息含loc指向typeof关键字位置的^^^^^^标记以及 Output--fix修复后的代码第二组invalid(1)~invalid(4)使用checkGlobalVariables: true选项运行的 4 个用例报错之外额外附带 Suggestion编辑器建议内容而没有 Output 自动修复。这种「输入 期望诊断 期望修复输出」的三元组正是 AVA 快照测试的价值所在只要 规则源码 的匹配条件、报错位置或修复逻辑发生任何变化运行npm run test:js见 package.json 中test:js脚本时快照比对就会失败从而保证修复行为被逐字符地锁定。默认模式基础替换与等号升级第一组快照的前 5 个用例覆盖了规则的全部触发形态。规则只匹配「左侧为typeof一元表达式、右侧为undefined字符串字面量、运算符属于、!、、!」的二元表达式这一判定逻辑位于 rules/no-typeof-undefined.js 的 L26-L42消息统一为Compare withundefineddirectly instead of usingtypeof.快照用例输入修复输出invalid(1)typeof a.b undefineda.b undefinedinvalid(2)typeof a.b ! undefineda.b ! undefinedinvalid(3)typeof a.b undefineda.b undefinedinvalid(4)typeof a.b ! undefineda.b ! undefinedinvalid(5)typeof a.b undefineda.b undefined值得注意的是 invalid(3) 与 invalid(4)规则在去掉typeof的同时把宽松的/!顺带升级成了严格的/!。这来自修复器生成器 L55-L64检测到运算符是或!时先找到该运算符 token再在其后插入一个。这样做是安全的因为typeof的返回值永远是字符串与undefined的比较不存在类型转换收益直接收紧为严格比较即可。invalid(5) 则证明单引号与双引号都被覆盖字符串字面量的判定使用isLiteral(node, undefined)见 L39 与 rules/ast/index.js而非简单比对 token 原文。默认模式作用域覆盖矩阵invalid(6) ~ invalid(17) 验证的是只要typeof的参数是一个本作用域内声明过的变量无论声明形式如何规则都会自动修复。快照中覆盖的形态包括快照用例声明形态修复输出invalid(6)let foo;let foo; foo undefinedinvalid(7)const foo 1;const foo 1; foo undefinedinvalid(8)var foo;var foo; foo undefinedinvalid(9)var foo; var foo;重复声明var foo; var foo; foo undefinedinvalid(10)for (const foo of bar)循环变量for (const foo of bar) foo undefined;invalid(11)外层let foo函数体内引用function bar() { foo undefined; }invalid(12)函数自身function foo() { ... foo ... }function foo() {foo undefined}invalid(13)简单参数function foo(bar)function foo(bar) {bar undefined}invalid(14)对象解构参数function foo({bar})function foo({bar}) {bar undefined}invalid(15)数组解构参数function foo([bar])function foo([bar]) {bar undefined}invalid(16)对象属性访问foo.barfoo.bar undefinedinvalid(17)ES Module 导入后访问属性import foo from foo;\nfoo.bar undefined这些用例对应的源码逻辑是规则先取typeof的操作数节点valueNode再通过isGlobalIdentifier(valueNode, context)判断它是否为全局标识符L46-L51。rules/utils/is-global-identifier.js 的实现是节点必须是Identifier并且要么sourceCode.isGlobalReference(node)为真即 ESLint 解析器已解析出它指向配置的全局变量要么是未解析变量隐式全局。let/const/var/参数/解构/导入绑定都不属于全局引用因此在默认选项下全部走自动修复路径。默认模式ASI 保护与括号处理快照中最容易忽略的修复细节集中在 invalid(18) ~ invalid(22)快照用例输入修复输出invalid(18)foo\ntypeof [] undefined;foo\n;[] undefined;invalid(19)foo\ntypeof (a ? b : c) undefined;foo\n;(a ? b : c) undefined;invalid(20)return typeof // comment\n a.b undefined;return ( // comment\n a.b undefined);invalid(21)return (typeof // 参数已加括号\n a.b undefined);return (// 参数已加括号\n a.b undefined);invalid(22)return (typeof // typeof 已加括号\n a.b) undefined;return (// typeof 已加括号\n a.b) undefined;ASI 保护invalid(18)(19)去掉typeof前缀后表达式可能以[或(开头。如果前一行是一个独立语句如foo自动分号插入会把代码解释成foo[...]或foo(...)。修复器通过needsSemicolon(tokenBefore, context, secondToken.value)L83-L86检查前置 token 与表达式首 token必要时在表达式前插入;。return/throw 换行加括号invalid(20)~(22)return后的表达式若跨行且以(开头同样存在被误读为函数调用的风险。修复器在 L71-L81 中检查父节点是ReturnStatement或ThrowStatement、参数就是这个二元表达式、typeof与下一个 token 不在同一行、且二元表达式和typeof节点本身都尚未被括号包裹时才调用addParenthesesToReturnOrThrowExpression来自 rules/fix/index.js补上括号。invalid(21)(22) 正是验证「已有括号则不重复添加」的反向场景。另外删除typeof关键字后的多余空格由removeSpacesAfter同样位于 rules/fix/index.js在 L68-L69 调用负责清理保证输出不会出现双空格。invalid(23) 则是普通场景收尾switch (typeof value undefined) {}→switch (value undefined) {}其中value是函数参数局部变量因此走自动修复。checkGlobalVariables从自动修复降级为 suggestion第二组快照4 个用例全部带Options: checkGlobalVariables: true标注展示的是规则对全局变量的处理快照用例输入Suggestion 输出invalid(1)typeof undefinedVariableIdentifier undefinedundefinedVariableIdentifier undefinedinvalid(2)typeof Array ! undefinedArray ! undefinedinvalid(3)未定义的value用于switchswitch (value undefined) {}invalid(4)/* globals value: readonly */声明的全局valueswitch (value undefined) {}这里有两个关键行为源码依据在 L89-L107默认选项下全局变量直接被忽略checkGlobalVariables默认falseL138 的defaultOptions命中全局引用时 L49-L51 直接return不报错。这与 规则文档 的说明一致对从未声明的变量直接写value undefined会抛出ReferenceError所以typeof在这种场景是唯一安全的探测方式文档建议改用globalThis.value undefined。开启选项后报 error 但只给 suggestioncheckGlobalVariables: true表示开发者接受这个风险此时问题对象挂的是problem.suggestsuggestion 消息模板为Switch to … {{operator}} undefined.运算符数据根据原运算符是否以!开头取!或见 L95-L102而不是problem.fix——即不会随--fix自动改写只能通过编辑器 suggestion 手动应用。invalid(2) 中Array ! undefined的 suggestion 输出Array ! undefined也印证了运算符映射原!保留为!。规则明确不报的边界valid 用例快照报告只渲染invalid区块但 test/no-typeof-undefined.js 的 L7-L36 定义了 15 个valid用例它们共同划定了规则的「不越权」边界其中几个值得注意typeof a.b、typeof a.b string比较值不是undefined不触发a.b undefined、void a.b undefined、a.b undefined、a.b undefined左侧不是typeof一元表达式不触发typeof foo undefinedfoo是未声明的全局变量默认选项下被有意忽略这正是checkGlobalVariables默认false的语义undefined typeof a.b字符串在右侧、typeof在左侧——从源码结构看匹配条件固定要求binaryExpression.left是typeof节点L27-L42交换顺序的写法不在检查范围内const UNDEFINED undefined; typeof a.b UNDEFINED、typeof a.b undefined右侧必须是字符串字面量isLiteral判定用变量或模板字符串存的undefined均不触发。规则元信息与启用方式从 meta 定义L127-L144 可以确认规则类型为suggestionfixable: code且hasSuggestions: true与 docs/rules/no-typeof-undefined.md 头部「 automatically fixable by--fixand manually fixable by editor suggestions」的描述一致schema 仅含checkGlobalVariables一个布尔选项且additionalProperties: false。该文档头部同时说明此规则在recommended与unopinionated配置集中启用。在 flat config 中单独开启并启用全局变量检查// eslint.config.js export default [ { rules: { // 开启后typeof 全局变量的写法会报 error // 修复方式降级为编辑器 suggestion不会自动 --fix unicorn/no-typeof-undefined: [error, {checkGlobalVariables: true}], }, }, ];如需回归验证本文描述的 27 个快照行为可运行npm run test:jspackage.json 中test:js即ava或直接针对该文件运行npx ava test/no-typeof-undefined.js任何修复输出的字符级差异都会让快照比对失败。小结这份快照报告以 27 个用例把no-typeof-undefined的行为钉死四种比较运算符全部归一为严格比较宽松等号顺带升级、本地绑定的各种声明形态均可安全修复、[]/(开头表达式有分号保护、跨行return/throw按需补括号且不重复补、全局变量默认放行、开启checkGlobalVariables后降级为 suggestion。对照 rules/no-typeof-undefined.js 的约 146 行实现可以清楚看到每一行快照输出背后对应的判定分支与修复步骤这也是「快照测试 精简规则实现」这一组合在 lint 插件仓库中的典型范式。【免费下载链接】eslint-plugin-unicornMore than 300 powerful ESLint rules项目地址: https://gitcode.com/GitHub_Trending/es/eslint-plugin-unicorn创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价