使用typescript-eslint自定义规则时,能否访问常量属性的值?
如何在自定义ESLint规则中获取常量属性值
你当前的规则只处理了kind属性是字符串字面量的情况,当属性值是JSX表达式(比如{CATEGORY_C})时,node.value的类型是TSESTree.JSXExpressionContainer,而非Literal,因此无法直接读取值。要获取这类常量的实际值,有两种可行方案:
方法一:通过作用域查找变量
适用于常量在当前或父作用域定义的场景,利用ESLint的作用域API定位变量定义并提取值:
import { ESLintUtils, TSESTree } from '@typescript-eslint/utils' const createRule = ESLintUtils.RuleCreator(() => '') const rule = createRule({ create(context) { return { 'JSXOpeningElement[name.name="Category"] JSXAttribute[name.name="kind"]': (node: TSESTree.JSXAttribute) => { let value: string | undefined; // 处理字符串字面量 if (node.value?.type === 'Literal') { value = node.value.value as string; } // 处理JSX表达式中的本地常量 else if (node.value?.type === 'JSXExpressionContainer' && node.value.expression.type === 'Identifier') { const variableName = node.value.expression.name; const scope = context.getScope(); // 查找变量定义 const variable = scope.variables.find(v => v.name === variableName); if (variable?.defs[0]?.type === 'Variable' && variable.defs[0].node.init?.type === 'Literal') { value = variable.defs[0].node.init.value as string; } } if (value && !/[A-Z]/.test(value)) { context.report({ node, messageId: 'message' }); } } }; }, messageIds: { message: 'Category组件的kind属性值不符合要求', }, // 补充其他规则配置(meta等) ... });
方法二:利用TypeScript类型检查器
如果常量是从其他文件导入的,作用域查找无法生效,此时可借助TypeScript的类型检查器追踪导入符号的实际值:
import { ESLintUtils, TSESTree } from '@typescript-eslint/utils' const createRule = ESLintUtils.RuleCreator(() => '') const rule = createRule({ create(context) { // 获取TypeScript解析服务 const services = ESLintUtils.getParserServices(context); const checker = services.program.getTypeChecker(); return { 'JSXOpeningElement[name.name="Category"] JSXAttribute[name.name="kind"]': (node: TSESTree.JSXAttribute) => { let value: string | undefined; // 处理字符串字面量 if (node.value?.type === 'Literal') { value = node.value.value as string; } // 处理JSX表达式中的导入常量 else if (node.value?.type === 'JSXExpressionContainer' && node.value.expression.type === 'Identifier') { const tsNode = services.esTreeNodeToTSNodeMap.get(node.value.expression); const symbol = checker.getSymbolAtLocation(tsNode); if (symbol?.valueDeclaration && symbol.valueDeclaration.kind === 10) { // SyntaxKind.StringLiteral对应数值10 value = (symbol.valueDeclaration as unknown as { text: string }).text; } } if (value && !/[A-Z]/.test(value)) { context.report({ node, messageId: 'message' }); } } }; }, messageIds: { message: 'Category组件的kind属性值不符合要求', }, meta: { type: 'suggestion', schema: [], }, // 补充其他规则配置 ... });
使用该方法需要确保你的ESLint配置已正确启用@typescript-eslint/parser解析器。
内容的提问来源于stack exchange,提问作者lctz
相关产品推荐
相关产品推荐

