forked from eslint-community/eslint-plugin-eslint-plugin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathno-property-in-node.js
58 lines (52 loc) · 1.61 KB
/
no-property-in-node.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
'use strict';
const { ESLintUtils } = require('@typescript-eslint/utils');
const tsutils = require('ts-api-utils');
const typedNodeSourceFileTesters = [
/@types[/\\]estree[/\\]index\.d\.ts/,
/@typescript-eslint[/\\]types[/\\]dist[/\\]generated[/\\]ast-spec\.d\.ts/,
];
/**
* @param {import('typescript').Type} type
* @returns Whether the type seems to include a known ESTree or TSESTree AST node.
*/
function isAstNodeType(type) {
return tsutils
.typeParts(type)
.flatMap((typePart) => typePart.symbol?.declarations ?? [])
.some((declaration) => {
const fileName = declaration.getSourceFile().fileName;
return (
fileName &&
typedNodeSourceFileTesters.some((tester) => tester.test(fileName))
);
});
}
/** @type {import('eslint').Rule.RuleModule} */
module.exports = {
meta: {
type: 'suggestion',
docs: {
description:
'disallow using `in` to narrow node types instead of looking at properties',
category: 'Rules',
recommended: true,
requiresTypeChecking: true,
url: 'https://github.com/eslint-community/eslint-plugin-eslint-plugin/tree/HEAD/docs/rules/no-property-in-node.md',
},
schema: [],
messages: {
in: 'Prefer checking specific node properties instead of a broad `in`.',
},
},
create(context) {
return {
'BinaryExpression[operator=in]'(node) {
const services = ESLintUtils.getParserServices(context);
const type = services.getTypeAtLocation(node.right);
if (isAstNodeType(type)) {
context.report({ messageId: 'in', node });
}
},
};
},
};