ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

eslint-plugin-unicorn no-undeclared-class-members:强制声明类成员的 ESLint 规则深入解析

eslint-plugin-unicorn no-undeclared-class-members:强制声明类成员的 ESLint 规则深入解析 Lint代码质量【免费下载链接】eslint-plugin-unicornMore than 300 powerful ESLint rules项目地址https://gitcode.com/GitHub_Trending/es/eslint-plugin-unicorn点击查看免费下载no-undeclared-class-members是 eslint-plugin-unicorn 提供的规则要求类成员字段、方法、getter、setter在使用前必须在类体内显式声明从而将拼写错误显性化并让读者一眼看清类的形状。本文以规则文档 docs/rules/no-undeclared-class-members.md 为骨架结合规则源码 rules/no-undeclared-class-members.js 与测试用例 test/no-undeclared-class-members.js从使用示例、判定逻辑、编辑器建议到 TypeScript 支持进行完整讲解帮助你理解它的边界行为并正确接入项目。规则概览启用配置与修复方式规则名no-undeclared-class-members规则类型problem问题类规则报告的是潜在的运行时错误而非风格分歧推荐配置在 ✅recommended配置中启用在 ☑️unopinionated配置中禁用修复方式 支持通过编辑器建议手动修复非自动 fix由开发者逐条确认这些元信息在规则源码的meta中均有对应声明type: problem、docs.recommended: true、hasSuggestions: true、schema: []无任何可配置选项参见 rules/no-undeclared-class-members.js。由于recommended: true规则会被自动纳入recommended预设配置中。核心动机让类成员「先声明后使用」规则文档给出的设计理念非常清晰Class members should be declared when they are used throughthis. Declaring fields, methods, getters, and setters in the class body makes typos visible and gives readers the class shape upfront.即通过this访问的类成员应当先在类体中声明。这样做的两个直接收益是让拼写错误可见this.nmae这种笔误在未声明时会被规则直接标记而不是在运行时静默得到undefined再抛出奇怪错误。让类的形状一目了然读者打开类定义即可看到全部字段和方法无需通读每个方法体去推断实例上有哪些属性。规则报告的消息为Class member \{{name}} is used but not declared.建议消息为Declare {{name}} as a class field.定义见 rules/no-undeclared-class-members.js。规则示例文档中的正反例规则文档给出了三组核心示例全部可以直接粘贴到 ESLint 规则测试或实际项目中验证。示例一读取字段// ❌ 未声明字段就被读取 class Foo { getName() { return this.name; } } // ✅ 显式声明字段 class Foo { name; getName() { return this.name; } }示例二调用方法// ❌ 未声明方法就被调用 class Foo { callName() { this.name(); } } // ✅ 显式声明方法 class Foo { name() {} callName() { this.name(); } }示例三构造函数赋值视为声明// ✅ 构造函数中的 this.name name 被视为声明 class Foo { constructor(name) { this.name name; } getName() { return this.name; } }测试文件中的等价用例逐一验证了上述场景见 test/no-undeclared-class-members.js。判定逻辑规则在源码层面如何工作规则采用「收集 后置判定」的两阶段设计见 rules/no-undeclared-class-members.js遍历阶段通过context.on(MemberExpression, ...)收集所有this.x形式的成员访问通过context.on(ClassBody, ...)收集所有类体。收尾阶段在context.onExit(Program)时对每个类体统计其「已声明成员名集合」再逐一检查收集到的成员访问是否命中声明集合。每个类体的报告流程由getProblemsForClassBody完成rules/no-undeclared-class-members.js报告需同时满足四个条件shouldReportMemberAccess见 rules/no-undeclared-class-members.js该成员访问所属的this归属类体与当前类体一致getThisOwnerClassBody会沿父链向上查找ClassBody并在遇到非类方法的普通函数时停止避免误判函数内部的独立this见 rules/no-undeclared-class-members.js不在静态上下文中isInStaticContext类体内static成员与静态块的this指向类本身而非实例不是类元素自身的定义例如字段初始化器name this.value中this.value的访问会被当作定义过程的一部分isClassElementDefinition见 rules/no-undeclared-class-members.js成员名不在已声明集合中。「已声明成员」的统计口径getDeclaredClassMemberNamesrules/no-undeclared-class-members.js会从三处收集声明类体中的静态命名成员非 static 的字段PropertyDefinition、方法MethodDefinition、getter/setterAccessorProperty以及 TS 抽象成员且键名必须是可静态确定的标识符、字符串字面量、无插值模板字面量见getStaticNamerules/no-undeclared-class-members.js。constructor会被预先加入集合。构造函数的参数属性TSconstructor(public name: string) {}这类TSParameterProperty会为对应名字登记声明含带默认值的AssignmentPattern见 rules/no-undeclared-class-members.js。构造函数内的简单赋值构造函数体中所有this.x ...形式运算符严格为的赋值表达式都会被当作声明。该遍历通过walkNode递归进行并会跳过嵌套的函数、箭头函数与类避免把闭包内对this的赋值算进来shouldSkip见 rules/no-undeclared-class-members.js。对extends类的豁免规则文档明确说明带extends的类会被整体忽略因为被访问的成员可能来自父类superclass。在源码中对应classBody.parent.superClass存在时直接continuerules/no-undeclared-class-members.js。测试用例class Foo extends Bar { getName() { return this.name; } }被判定为合法验证了这一行为test/no-undeclared-class-members.js。边界行为哪些情况不会报告规则文档列出了明确的不支持/不报告场景均有对应测试佐证场景原因测试位置static方法内的this.name静态上下文中this指向类本身不是实例成员test/no-undeclared-class-members.js静态块static { this.name foo; }同上静态上下文test/no-undeclared-class-members.js私有成员this.#name私有成员天然必须在类体声明不存在「未声明」问题test/no-undeclared-class-members.js计算访问this[name]键名无法静态确定test/no-undeclared-class-members.js动态初始化Object.assign(this, data)属性名来自外部数据无法静态分析test/no-undeclared-class-members.jsthis.constructorconstructor恒被预先登记为已声明test/no-undeclared-class-members.js普通函数内的thisgetThisOwnerClassBody在非类方法函数处停止this归属函数自身test/no-undeclared-class-members.js编辑器建议Suggestion何时提供、如何插入规则虽然不做自动修复但会对简单赋值场景提供编辑器建议。具体条件见 rules/no-undeclared-class-members.js成员访问是简单赋值目标this.name name且运算符为isSimpleAssignmentTargetrules/no-undeclared-class-members.js不在构造函数中构造函数赋值已被视为声明自然不需要建议每个名字只建议一次。而读取、调用、复合赋值、自增自减以及构造函数内的赋值都只报告错误、不提供建议。测试中的this.name name与this.name用例正是复合赋值与更新的代表test/no-undeclared-class-members.js。建议的插入逻辑getInsertClassFieldSuggestionrules/no-undeclared-class-members.js会若类体非空以第一个成员前的注释或成员为插入锚点按成员缩进 name ;的格式插入字段声明并跳过首成员与左花括号同行的单行类此时无法干净插入若类体为空在右花括号前插入带缩进的name;声明缩进通过 rules/utils/get-indent-string.js 从上下文行首空白推导保证插入结果与代码风格一致。重要注意字段声明会改变可观察行为规则文档特别强调了一个容易被忽略的运行时差异Declaring a class field likename;creates an own property with the valueundefinedon every instance before any method runs. This can change observable behavior, for exampleObject.hasOwn(instance, name), so this rule provides editor suggestions instead of an autofix.即name;这样的字段声明会在每个实例上、在任何方法执行前创建一个值为undefined的自有属性。这会改变可观察行为例如Object.hasOwn(instance, name)的结果会从false变为true。正是因为这个原因规则只提供编辑器建议需人工确认而不是直接自动修复避免在不经意间改变程序语义。TypeScript 支持规则完整支持 TypeScript 语法测试见 test/no-undeclared-class-members.js视为已声明的 TS 写法class Foo { declare name: string; // declare 字段声明 getName() { return this.name; } } abstract class Foo { abstract name: string; // 抽象字段 getName() { return this.name; } } class Foo { constructor(public name: string) {} // 参数属性 getName() { return this.name; } }会报告的 TS 写法// ❌ 普通构造函数参数不会声明成员 class Foo { constructor(name: string) {} getName() { return this.name; } } // ❌ 类型断言包裹的 this 访问同样被追踪 class Foo { getName() { return this.name as string; } } // ❌ 非空断言 this!.name 同样被追踪 class Foo { getName() { return this!.name; } }源码层面TS 的支持体现在两个集合classMemberTypes中包含了TSAbstractAccessorProperty、TSAbstractMethodDefinition、TSAbstractPropertyDefinition三类抽象成员rules/no-undeclared-class-members.js而transparentExpressionWrapperTypes中的TSAsExpression、TSNonNullExpression、TSSatisfiesExpression、TSTypeAssertion、TSInstantiationExpression等包装节点会被透明剥离后再判断是否为thisrules/no-undeclared-class-members.js。此外规则还声明了languages: [js/js]仅面向 JavaScript/TypeScript 代码。如何接入项目no-undeclared-class-members已包含在recommended预设中使用官方推荐配置即可直接生效// eslint.config.jsflat config import unicorn from eslint-plugin-unicorn; export default [ unicorn.configs.recommended, // ... ];如需在非recommended的配置中单独启用export default [ { plugins: {unicorn}, rules: { unicorn/no-undeclared-class-members: error, }, }, ];该规则没有任何配置选项schema: []开关注入error或warn即可。在启用前建议先结合本文「边界行为」一节确认代码库中是否存在extends继承、静态成员、Object.assign动态赋值等豁免场景避免误报干扰同时留意「字段声明改变可观察行为」的注意事项对编辑器建议逐条人工确认后再应用。赞分享Lint代码质量【免费下载链接】eslint-plugin-unicornMore than 300 powerful ESLint rules项目地址https://gitcode.com/GitHub_Trending/es/eslint-plugin-unicorn点击查看免费下载相关推荐读懂 no-undeclared-class-members从 eslint-plugin-unicorn 的测试快照报告解析类成员未声明检测规则读懂 no undeclared class members从 eslint plugin unicorn 的测试快照报告解析类成员未声明检测规则 本文以仓库Lint代码质量Kafka KRaft 集群 SCRAM 凭据管理从格式化到删除的完整路径Kafka KRaft 集群 SCRAM 凭据管理从格式化到删除的完整路径 Kafka KRaft 集群的 SCRAM 凭据管理容易走偏因为 KRaft 模后端消息队列流处理大数据ESLint 规则深度解析no-unused-private-class-members 检测未使用的私有类成员ESLint 规则深度解析no unused private class members 检测未使用的私有类成员 本文基于 ESLint 官方文档 docs/开发工具Lint静态分析代码质量上一篇职业价值量化评估工具深度解析worth-calculator如何重塑职业决策下一篇探索数据新维度WrenAI - 无需SQL的智能问答平台创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表