Skip to content

Commit 6cdef14

Browse files
feat: no-property-in-node add additionalNodeTypeFiles option (#484)
1 parent 04e397b commit 6cdef14

File tree

2 files changed

+64
-4
lines changed

2 files changed

+64
-4
lines changed

Diff for: lib/rules/no-property-in-node.js

+25-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use strict';
22

3-
const typedNodeSourceFileTesters = [
3+
const defaultTypedNodeSourceFileTesters = [
44
/@types[/\\]estree[/\\]index\.d\.ts/,
55
/@typescript-eslint[/\\]types[/\\]dist[/\\]generated[/\\]ast-spec\.d\.ts/,
66
];
@@ -26,9 +26,10 @@ const typedNodeSourceFileTesters = [
2626
* ```
2727
*
2828
* @param {import('typescript').Type} type
29+
* @param {RegExp[]} typedNodeSourceFileTesters
2930
* @returns Whether the type seems to include a known ESTree or TSESTree AST node.
3031
*/
31-
function isAstNodeType(type) {
32+
function isAstNodeType(type, typedNodeSourceFileTesters) {
3233
return (type.types || [type])
3334
.filter((typePart) => typePart.getProperty('type'))
3435
.flatMap(
@@ -55,13 +56,33 @@ module.exports = {
5556
requiresTypeChecking: true,
5657
url: 'https://github.com/eslint-community/eslint-plugin-eslint-plugin/tree/HEAD/docs/rules/no-property-in-node.md',
5758
},
58-
schema: [],
59+
schema: [
60+
{
61+
type: 'object',
62+
properties: {
63+
additionalNodeTypeFiles: {
64+
description:
65+
'Any additional regular expressions to consider source files defining AST Node types.',
66+
elements: { type: 'string' },
67+
type: 'array',
68+
},
69+
},
70+
additionalProperties: false,
71+
},
72+
],
5973
messages: {
6074
in: 'Prefer checking specific node properties instead of a broad `in`.',
6175
},
6276
},
6377

6478
create(context) {
79+
const typedNodeSourceFileTesters = [
80+
...defaultTypedNodeSourceFileTesters,
81+
...(context.options[0]?.additionalNodeTypeFiles?.map(
82+
(filePath) => new RegExp(filePath),
83+
) ?? []),
84+
];
85+
6586
return {
6687
'BinaryExpression[operator=in]'(node) {
6788
// TODO: Switch this to ESLintUtils.getParserServices with typescript-eslint@>=6
@@ -77,7 +98,7 @@ module.exports = {
7798
const tsNode = services.esTreeNodeToTSNodeMap.get(node.right);
7899
const type = checker.getTypeAtLocation(tsNode);
79100

80-
if (isAstNodeType(type)) {
101+
if (isAstNodeType(type, typedNodeSourceFileTesters)) {
81102
context.report({ messageId: 'in', node });
82103
}
83104
},

Diff for: tests/lib/rules/no-property-in-node.js

+39
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,21 @@ ruleTester.run('no-property-in-node', rule, {
9393
},
9494
};
9595
`,
96+
{
97+
code: `
98+
interface Node {
99+
type: string;
100+
}
101+
declare const node: Node;
102+
'a' in node;
103+
export {};
104+
`,
105+
options: [
106+
{
107+
additionalNodeTypeFiles: [/not-found/],
108+
},
109+
],
110+
},
96111
],
97112
invalid: [
98113
{
@@ -163,5 +178,29 @@ ruleTester.run('no-property-in-node', rule, {
163178
},
164179
],
165180
},
181+
{
182+
code: `
183+
interface Node {
184+
type: string;
185+
}
186+
declare const node: Node;
187+
'a' in node;
188+
export {};
189+
`,
190+
options: [
191+
{
192+
additionalNodeTypeFiles: [/lib[/\\]fixtures[/\\]estree\.ts/],
193+
},
194+
],
195+
errors: [
196+
{
197+
column: 9,
198+
line: 6,
199+
endColumn: 20,
200+
endLine: 6,
201+
messageId: 'in',
202+
},
203+
],
204+
},
166205
],
167206
});

0 commit comments

Comments
 (0)