UNPKG

8.35 kBJavaScriptView Raw
1"use strict";
2var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3 if (k2 === undefined) k2 = k;
4 Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5}) : (function(o, m, k, k2) {
6 if (k2 === undefined) k2 = k;
7 o[k2] = m[k];
8}));
9var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10 Object.defineProperty(o, "default", { enumerable: true, value: v });
11}) : function(o, v) {
12 o["default"] = v;
13});
14var __importStar = (this && this.__importStar) || function (mod) {
15 if (mod && mod.__esModule) return mod;
16 var result = {};
17 if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18 __setModuleDefault(result, mod);
19 return result;
20};
21Object.defineProperty(exports, "__esModule", { value: true });
22const utils_1 = require("@typescript-eslint/utils");
23const util = __importStar(require("../util"));
24exports.default = util.createRule({
25 name: 'no-explicit-any',
26 meta: {
27 type: 'suggestion',
28 docs: {
29 description: 'Disallow usage of the `any` type',
30 recommended: 'warn',
31 suggestion: true,
32 },
33 fixable: 'code',
34 hasSuggestions: true,
35 messages: {
36 unexpectedAny: 'Unexpected any. Specify a different type.',
37 suggestUnknown: 'Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct.',
38 suggestNever: "Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of.",
39 },
40 schema: [
41 {
42 type: 'object',
43 additionalProperties: false,
44 properties: {
45 fixToUnknown: {
46 type: 'boolean',
47 },
48 ignoreRestArgs: {
49 type: 'boolean',
50 },
51 },
52 },
53 ],
54 },
55 defaultOptions: [
56 {
57 fixToUnknown: false,
58 ignoreRestArgs: false,
59 },
60 ],
61 create(context, [{ ignoreRestArgs, fixToUnknown }]) {
62 /**
63 * Checks if the node is an arrow function, function/constructor declaration or function expression
64 * @param node the node to be validated.
65 * @returns true if the node is any kind of function declaration or expression
66 * @private
67 */
68 function isNodeValidFunction(node) {
69 return [
70 utils_1.AST_NODE_TYPES.ArrowFunctionExpression,
71 utils_1.AST_NODE_TYPES.FunctionDeclaration,
72 utils_1.AST_NODE_TYPES.FunctionExpression,
73 utils_1.AST_NODE_TYPES.TSEmptyBodyFunctionExpression,
74 utils_1.AST_NODE_TYPES.TSFunctionType,
75 utils_1.AST_NODE_TYPES.TSConstructorType,
76 utils_1.AST_NODE_TYPES.TSCallSignatureDeclaration,
77 utils_1.AST_NODE_TYPES.TSConstructSignatureDeclaration,
78 utils_1.AST_NODE_TYPES.TSMethodSignature,
79 utils_1.AST_NODE_TYPES.TSDeclareFunction, // declare function _8(...args: any[]): unknown;
80 ].includes(node.type);
81 }
82 /**
83 * Checks if the node is a rest element child node of a function
84 * @param node the node to be validated.
85 * @returns true if the node is a rest element child node of a function
86 * @private
87 */
88 function isNodeRestElementInFunction(node) {
89 return (node.type === utils_1.AST_NODE_TYPES.RestElement &&
90 typeof node.parent !== 'undefined' &&
91 isNodeValidFunction(node.parent));
92 }
93 /**
94 * Checks if the node is a TSTypeOperator node with a readonly operator
95 * @param node the node to be validated.
96 * @returns true if the node is a TSTypeOperator node with a readonly operator
97 * @private
98 */
99 function isNodeReadonlyTSTypeOperator(node) {
100 return (node.type === utils_1.AST_NODE_TYPES.TSTypeOperator &&
101 node.operator === 'readonly');
102 }
103 /**
104 * Checks if the node is a TSTypeReference node with an Array identifier
105 * @param node the node to be validated.
106 * @returns true if the node is a TSTypeReference node with an Array identifier
107 * @private
108 */
109 function isNodeValidArrayTSTypeReference(node) {
110 return (node.type === utils_1.AST_NODE_TYPES.TSTypeReference &&
111 typeof node.typeName !== 'undefined' &&
112 node.typeName.type === utils_1.AST_NODE_TYPES.Identifier &&
113 ['Array', 'ReadonlyArray'].includes(node.typeName.name));
114 }
115 /**
116 * Checks if the node is a valid TSTypeOperator or TSTypeReference node
117 * @param node the node to be validated.
118 * @returns true if the node is a valid TSTypeOperator or TSTypeReference node
119 * @private
120 */
121 function isNodeValidTSType(node) {
122 return (isNodeReadonlyTSTypeOperator(node) ||
123 isNodeValidArrayTSTypeReference(node));
124 }
125 /**
126 * Checks if the great grand-parent node is a RestElement node in a function
127 * @param node the node to be validated.
128 * @returns true if the great grand-parent node is a RestElement node in a function
129 * @private
130 */
131 function isGreatGrandparentRestElement(node) {
132 var _a, _b;
133 return (((_b = (_a = node === null || node === void 0 ? void 0 : node.parent) === null || _a === void 0 ? void 0 : _a.parent) === null || _b === void 0 ? void 0 : _b.parent) != null &&
134 isNodeRestElementInFunction(node.parent.parent.parent));
135 }
136 /**
137 * Checks if the great great grand-parent node is a valid RestElement node in a function
138 * @param node the node to be validated.
139 * @returns true if the great great grand-parent node is a valid RestElement node in a function
140 * @private
141 */
142 function isGreatGreatGrandparentRestElement(node) {
143 var _a, _b, _c;
144 return (((_c = (_b = (_a = node.parent) === null || _a === void 0 ? void 0 : _a.parent) === null || _b === void 0 ? void 0 : _b.parent) === null || _c === void 0 ? void 0 : _c.parent) != null &&
145 isNodeValidTSType(node.parent.parent) &&
146 isNodeRestElementInFunction(node.parent.parent.parent.parent));
147 }
148 /**
149 * Checks if the great grand-parent or the great great grand-parent node is a RestElement node
150 * @param node the node to be validated.
151 * @returns true if the great grand-parent or the great great grand-parent node is a RestElement node
152 * @private
153 */
154 function isNodeDescendantOfRestElementInFunction(node) {
155 return (isGreatGrandparentRestElement(node) ||
156 isGreatGreatGrandparentRestElement(node));
157 }
158 return {
159 TSAnyKeyword(node) {
160 if (ignoreRestArgs && isNodeDescendantOfRestElementInFunction(node)) {
161 return;
162 }
163 const fixOrSuggest = {
164 fix: null,
165 suggest: [
166 {
167 messageId: 'suggestUnknown',
168 fix(fixer) {
169 return fixer.replaceText(node, 'unknown');
170 },
171 },
172 {
173 messageId: 'suggestNever',
174 fix(fixer) {
175 return fixer.replaceText(node, 'never');
176 },
177 },
178 ],
179 };
180 if (fixToUnknown) {
181 fixOrSuggest.fix = (fixer) => fixer.replaceText(node, 'unknown');
182 }
183 context.report(Object.assign({ node, messageId: 'unexpectedAny' }, fixOrSuggest));
184 },
185 };
186 },
187});
188//# sourceMappingURL=no-explicit-any.js.map
\No newline at end of file