寻求可检测未校验对象及子属性访问的JavaScript Linter工具
适配JavaScript的对象属性访问校验Linter方案
你需要的核心功能点:
- 拦截直接访问未做存在性校验的对象属性,比如
const x = foo.prop要报错,得写成const x = foo && foo.prop - 揪出只校验父对象但漏校验子属性的情况,比如
const x = foo && foo.prop.prop2这种也要报错 - 不能用
?.语法,得兼容旧浏览器 - 不管是ESLint插件、Husky提交钩子都能接受
下面是几个可行的实现方案:
1. 自己写ESLint自定义规则
既然找不到现成的JS插件,自定义规则是最灵活的路子。核心思路是遍历代码的AST,识别链式属性访问,逐个检查每一层父对象是否通过&&做了存在性校验。
给你一个基础的规则骨架,你可以根据自己的项目场景扩展完善:
module.exports = { meta: { type: "problem", docs: { description: "强制访问嵌套属性前校验所有父级对象存在性" }, fixable: null, }, create(context) { function checkNestedAccess(node) { let current = node; while (current.type === "MemberExpression") { const parentObj = current.object; // 检查当前父对象是否经过&&校验 if (!(parentObj.type === "LogicalExpression" && parentObj.operator === "&&")) { context.report({ node: current, message: `访问属性'${current.property.name}'前未校验'${context.getSourceCode().getText(parentObj)}'是否存在`, }); break; } current = parentObj.left; } } return { MemberExpression(node) { // 排除函数调用后的属性访问,比如foo().bar这种场景(可根据需求调整) if (node.object.type !== "CallExpression") { checkNestedAccess(node); } }, }; }, };
把这个规则加到你的ESLint配置里,再配合Husky做提交前的代码校验,就能覆盖你的需求。
2. 扩展ESLint原生规则no-unsafe-member-access
ESLint自带的no-unsafe-member-access规则可以基础校验不安全的属性访问,但默认只检查顶层。你可以基于这个规则做扩展,修改它的判断逻辑,让它递归检查所有嵌套层级的父对象是否都做了存在性校验,这样不用从零写规则。
3. 用TypeScript静态检查兼容JS项目
虽然你用的是JavaScript,但可以不用全量迁移到TS,只启用TS的静态检查功能。步骤如下:
- 项目里创建
tsconfig.json,设置allowJs: true、checkJs: true - 安装
@typescript-eslint/eslint-plugin和@typescript-eslint/parser - 在ESLint配置中启用
@typescript-eslint/no-unsafe-member-access规则
这种方式利用TS的类型系统做静态检查,不需要改JS代码,还能快速实现你要的校验逻辑。如果有些对象结构TS识别不了,加个/** @type {Object} */这样的类型注释就能解决。
注意点
- 自定义ESLint规则时,要考虑函数返回值属性访问、全局变量等边界场景,逐步完善规则逻辑
- 用TS检查JS项目时,可能需要调整
tsconfig里的类型检查严格程度,避免不必要的报错
内容的提问来源于stack exchange,提问作者ctpet
相关产品推荐
相关产品推荐

