From 5ff29cdb86df22fc32d7d9a067e61e517e223da2 Mon Sep 17 00:00:00 2001 From: Benjamin Lichtman Date: Mon, 28 Jan 2019 11:12:10 -0800 Subject: [PATCH 1/5] feat(eslint-plugin): add new rule no-for-in-array --- packages/eslint-plugin/README.md | 2 + packages/eslint-plugin/ROADMAP.md | 25 ++++--- .../docs/rules/no-for-in-array.md | 36 +++++++++ packages/eslint-plugin/jsconfig.json | 8 ++ .../lib/rules/no-for-in-array.js | 57 ++++++++++++++ packages/eslint-plugin/lib/util.js | 6 +- .../tests/lib/rules/no-for-in-array.js | 75 +++++++++++++++++++ 7 files changed, 196 insertions(+), 13 deletions(-) create mode 100644 packages/eslint-plugin/docs/rules/no-for-in-array.md create mode 100644 packages/eslint-plugin/jsconfig.json create mode 100644 packages/eslint-plugin/lib/rules/no-for-in-array.js create mode 100644 packages/eslint-plugin/tests/lib/rules/no-for-in-array.js diff --git a/packages/eslint-plugin/README.md b/packages/eslint-plugin/README.md index 4f6f771d47c4..fc468e827ee8 100644 --- a/packages/eslint-plugin/README.md +++ b/packages/eslint-plugin/README.md @@ -96,6 +96,8 @@ See [@typescript-eslint/parser's README.md](../parser/README.md) for more inform | [`@typescript-eslint/no-empty-interface`](./docs/rules/no-empty-interface.md) | Disallow the declaration of empty interfaces (`no-empty-interface` from TSLint) | :heavy_check_mark: | | | [`@typescript-eslint/no-explicit-any`](./docs/rules/no-explicit-any.md) | Disallow usage of the `any` type (`no-any` from TSLint) | :heavy_check_mark: | | | [`@typescript-eslint/no-extraneous-class`](./docs/rules/no-extraneous-class.md) | Forbids the use of classes as namespaces (`no-unnecessary-class` from TSLint) | | | +| [`typescript/no-for-in-array`](./docs/rules/no-for-in-array.md) | Disallow iterating over an array with a for-in loop (`no-for-in-array` from TSLint) + | | | | [`@typescript-eslint/no-inferrable-types`](./docs/rules/no-inferrable-types.md) | Disallows explicit type declarations for variables or parameters initialized to a number, string, or boolean. (`no-inferrable-types` from TSLint) | :heavy_check_mark: | :wrench: | | [`@typescript-eslint/no-misused-new`](./docs/rules/no-misused-new.md) | Enforce valid definition of `new` and `constructor`. (`no-misused-new` from TSLint) | :heavy_check_mark: | | | [`@typescript-eslint/no-namespace`](./docs/rules/no-namespace.md) | Disallow the use of custom TypeScript modules and namespaces (`no-namespace` from TSLint) | :heavy_check_mark: | | diff --git a/packages/eslint-plugin/ROADMAP.md b/packages/eslint-plugin/ROADMAP.md index 1fce16992a9c..6d196bc48457 100644 --- a/packages/eslint-plugin/ROADMAP.md +++ b/packages/eslint-plugin/ROADMAP.md @@ -1,9 +1,9 @@ # Roadmap -βœ… (27) = done -🌟 (79) = in ESLint core -πŸ”Œ (33) = in another plugin -πŸŒ“ (16) = implementations differ or ESLint version is missing functionality +βœ… (27) = done +🌟 (79) = in ESLint core +πŸ”Œ (33) = in another plugin +πŸŒ“ (16) = implementations differ or ESLint version is missing functionality πŸ›‘ (71) = unimplemented ## TSLint rules @@ -59,6 +59,7 @@ | [`no-empty`] | 🌟 | [`no-empty`][no-empty] | | [`no-eval`] | 🌟 | [`no-eval`][no-eval] | | [`no-floating-promises`] | πŸ›‘ | N/A ([relevant plugin][plugin:promise]) | +| [`no-for-in-array`] | βœ… | [`typescript/no-for-in-array`] | | [`no-for-in-array`] | πŸ›‘ | N/A | | [`no-implicit-dependencies`] | πŸ”Œ | [`import/no-extraneous-dependencies`] | | [`no-inferred-empty-object-type`] | πŸ›‘ | N/A | @@ -96,7 +97,7 @@ | [`use-default-type-parameter`] | πŸ›‘ | N/A | | [`use-isnan`] | 🌟 | [`use-isnan`][use-isnan] | -[1] The ESLint rule also supports silencing with an extra set of parens (`if ((foo = bar)) {}`) +[1] The ESLint rule also supports silencing with an extra set of parens (`if ((foo = bar)) {}`) [2] Missing private class member support. [`@typescript-eslint/no-unused-vars`] adds support for some TS-specific features. ### Maintainability @@ -120,7 +121,7 @@ | [`prefer-readonly`] | πŸ›‘ | N/A | | [`trailing-comma`] | πŸŒ“ | [`comma-dangle`][comma-dangle] or [Prettier] | -[1] Only warns when importing deprecated symbols +[1] Only warns when importing deprecated symbols [2] Missing support for blank-line-delimited sections ### Style @@ -179,7 +180,7 @@ | [`variable-name`] | 🌟 | [2] | | [`whitespace`] | πŸ”Œ | Use [Prettier] | -[1] Recommended config: `["error", { blankLine: "always", prev: "*", next: "return" }]` +[1] Recommended config: `["error", { blankLine: "always", prev: "*", next: "return" }]` [2] [`camelcase`][camelcase], [`no-underscore-dangle`][no-underscore-dangle], [`id-blacklist`][id-blacklist], and/or [`id-match`][id-match] ## tslint-microsoft-contrib rules @@ -245,10 +246,10 @@ Relevant plugins: [`chai-expect-keywords`](https://github.com/gavinaiken/eslint- | `use-named-parameter` | πŸ›‘ | N/A | | `use-simple-attributes` | πŸ›‘ | N/A | -[1] Enforces blank lines both at the beginning and end of a block -[2] Recommended config: `["error", "ForInStatement"]` -[3] Recommended config: `["error", "declaration", { "allowArrowFunctions": true }]` -[4] Recommended config: `["error", { "terms": ["BUG", "HACK", "FIXME", "LATER", "LATER2", "TODO"], "location": "anywhere" }]` +[1] Enforces blank lines both at the beginning and end of a block +[2] Recommended config: `["error", "ForInStatement"]` +[3] Recommended config: `["error", "declaration", { "allowArrowFunctions": true }]` +[4] Recommended config: `["error", { "terms": ["BUG", "HACK", "FIXME", "LATER", "LATER2", "TODO"], "location": "anywhere" }]` [5] Does not check class fields. [insecure-random]: https://github.com/desktop/desktop/blob/master/eslint-rules/insecure-random.js @@ -310,7 +311,7 @@ Relevant plugins: [`chai-expect-keywords`](https://github.com/gavinaiken/eslint- | `react-a11y-titles` | πŸ›‘ | N/A | | `react-anchor-blank-noopener` | πŸ›‘ | N/A | -[1] TSLint rule is more strict +[1] TSLint rule is more strict [2] ESLint rule only reports for click handlers [prettier]: https://prettier.io diff --git a/packages/eslint-plugin/docs/rules/no-for-in-array.md b/packages/eslint-plugin/docs/rules/no-for-in-array.md new file mode 100644 index 000000000000..89aed236bac2 --- /dev/null +++ b/packages/eslint-plugin/docs/rules/no-for-in-array.md @@ -0,0 +1,36 @@ +# Disallow iterating over an array with a for-in loop (no-for-in-array) + +This rule prohibits iterating over an array with a for-in loop. + +## Rule Details + +Rationale from TSLint: + +> A for-in loop (for (var k in o)) iterates over the properties of an Object. +> While it is legal to use for-in loops with array types, it is not common. for-in will iterate over the indices of the array as strings, omitting any β€œholes” in the array. +> More common is to use for-of, which iterates over the values of an array. If you want to iterate over the indices, alternatives include: +> array.forEach((value, index) => { … }); for (const [index, value] of array.entries()) { … } for (let i = 0; i < array.length; i++) { … } + +Examples of **incorrect** code for this rule: + +```js +for (const x in [3, 4, 5]) { + console.log(x); +} +``` + +Examples of **correct** code for this rule: + +```js +for (const x in { a: 3, b: 4, c: 5 }) { + console.log(x); +} +``` + +## When Not To Use It + +If you want to iterate through a loop using the indices in an array as strings, you can turn off this rule. + +## Related to + +- TSLint: ['no-for-in-array'](https://palantir.github.io/tslint/rules/no-for-in-array/) diff --git a/packages/eslint-plugin/jsconfig.json b/packages/eslint-plugin/jsconfig.json new file mode 100644 index 000000000000..d68b67d6e404 --- /dev/null +++ b/packages/eslint-plugin/jsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "target": "es2015", + "checkJs": true, + "strict": true, + "module": "commonjs" + } +} diff --git a/packages/eslint-plugin/lib/rules/no-for-in-array.js b/packages/eslint-plugin/lib/rules/no-for-in-array.js new file mode 100644 index 000000000000..3d8e9ad00eff --- /dev/null +++ b/packages/eslint-plugin/lib/rules/no-for-in-array.js @@ -0,0 +1,57 @@ +/** + * @fileoverview Disallow iterating over an array with a for-in loop + * @author Benjamin Lichtman + */ +'use strict'; +const ts = require('typescript'); +const util = require('../util'); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +/** + * @type {import("eslint").Rule.RuleModule} + */ +module.exports = { + meta: { + docs: { + description: 'Disallow iterating over an array with a for-in loop', + category: 'Functionality', + recommended: false, + extraDescription: [util.tslintRule('no-for-in-array')], + url: util.metaDocsUrl('no-for-in-array') + }, + fixable: null, + schema: [], + type: 'problem' + }, + + create(context) { + return { + ForInStatement(node) { + const parserServices = util.getParserServices(context); + const checker = parserServices.program.getTypeChecker(); + const originalNode = parserServices.esTreeNodeToTSNodeMap.get(node); + + if (!originalNode) { + return; + } + + const type = checker.getTypeAtLocation(originalNode.expression); + + if ( + (typeof type.symbol !== 'undefined' && + type.symbol.name === 'Array') || + (type.flags & ts.TypeFlags.StringLike) !== 0 + ) { + context.report({ + node, + message: + 'For-in loops over arrays are forbidden. Use for-of or array.forEach instead.' + }); + } + } + }; + } +}; diff --git a/packages/eslint-plugin/lib/util.js b/packages/eslint-plugin/lib/util.js index e12e15f80413..6efcc7dfe219 100644 --- a/packages/eslint-plugin/lib/util.js +++ b/packages/eslint-plugin/lib/util.js @@ -1,5 +1,9 @@ 'use strict'; +/** @typedef {import("eslint").Rule.RuleContext} RuleContext */ +/** @typedef {WeakMap} NodeMap */ +/** @typedef {import("typescript").Program} Program */ + const version = require('../package.json').version; exports.tslintRule = name => `\`${name}\` from TSLint`; @@ -109,7 +113,7 @@ exports.upperCaseFirst = str => str[0].toUpperCase() + str.slice(1); /** * Try to retrieve typescript parser service from context * @param {RuleContext} context Rule context - * @returns {{esTreeNodeToTSNodeMap}|{program}|Object|*} parserServices + * @returns {{program: Program, esTreeNodeToTSNodeMap: NodeMap}} parserServices */ exports.getParserServices = context => { if ( diff --git a/packages/eslint-plugin/tests/lib/rules/no-for-in-array.js b/packages/eslint-plugin/tests/lib/rules/no-for-in-array.js new file mode 100644 index 000000000000..94a3200608a4 --- /dev/null +++ b/packages/eslint-plugin/tests/lib/rules/no-for-in-array.js @@ -0,0 +1,75 @@ +/** + * @fileoverview Disallow iterating over an array with a for-in loop + * @author Benjamin Lichtman + */ +'use strict'; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const rule = require('../../../lib/rules/no-for-in-array'), + RuleTester = require('eslint').RuleTester, + path = require('path'); + +//------------------------------------------------------------------------------ +// Tests +//------------------------------------------------------------------------------ + +// RuleTester.it = function(text, method) { +// return method.call({ break: true }); +// }; + +const rootDir = path.join(process.cwd(), 'tests/fixtures/'); +const parserOptions = { + ecmaVersion: 2015, + tsconfigRootDir: rootDir, + project: './tsconfig.json' +}; +const ruleTester = new RuleTester({ + parserOptions, + parser: '@typescript-eslint/parser' +}); +const message = + 'For-in loops over arrays are forbidden. Use for-of or array.forEach instead.'; + +ruleTester.run('no-for-in-array', rule, { + valid: [ + ` +for (const x of [3, 4, 5]) { + console.log(x); +}`, + ` +for (const x in { a: 1, b: 2, c: 3 }) { + console.log(x); +}` + ], + + invalid: [ + { + code: ` +for (const x in [3, 4, 5]) { + console.log(x); +}`, + errors: [ + { + message, + type: 'ForInStatement' + } + ] + }, + { + code: ` +const z = [3, 4, 5]; +for (const x in z) { + console.log(x); +}`, + errors: [ + { + message, + type: 'ForInStatement' + } + ] + } + ] +}); From 7d9991e65b11f5b875d2a7468c540161cd910069 Mon Sep 17 00:00:00 2001 From: Benjamin Lichtman Date: Mon, 28 Jan 2019 12:59:38 -0800 Subject: [PATCH 2/5] chore(eslint-plugin): remove unnecessary typedefs --- packages/eslint-plugin/lib/util.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/eslint-plugin/lib/util.js b/packages/eslint-plugin/lib/util.js index 6efcc7dfe219..26cf0e454767 100644 --- a/packages/eslint-plugin/lib/util.js +++ b/packages/eslint-plugin/lib/util.js @@ -1,9 +1,5 @@ 'use strict'; -/** @typedef {import("eslint").Rule.RuleContext} RuleContext */ -/** @typedef {WeakMap} NodeMap */ -/** @typedef {import("typescript").Program} Program */ - const version = require('../package.json').version; exports.tslintRule = name => `\`${name}\` from TSLint`; From a33344877b5115dcb7ae66f3886468cc61b31fdf Mon Sep 17 00:00:00 2001 From: Benjamin Lichtman Date: Mon, 28 Jan 2019 13:51:36 -0800 Subject: [PATCH 3/5] chore: fix README spacing --- packages/eslint-plugin/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/eslint-plugin/README.md b/packages/eslint-plugin/README.md index fc468e827ee8..a6082d5fc84f 100644 --- a/packages/eslint-plugin/README.md +++ b/packages/eslint-plugin/README.md @@ -96,8 +96,7 @@ See [@typescript-eslint/parser's README.md](../parser/README.md) for more inform | [`@typescript-eslint/no-empty-interface`](./docs/rules/no-empty-interface.md) | Disallow the declaration of empty interfaces (`no-empty-interface` from TSLint) | :heavy_check_mark: | | | [`@typescript-eslint/no-explicit-any`](./docs/rules/no-explicit-any.md) | Disallow usage of the `any` type (`no-any` from TSLint) | :heavy_check_mark: | | | [`@typescript-eslint/no-extraneous-class`](./docs/rules/no-extraneous-class.md) | Forbids the use of classes as namespaces (`no-unnecessary-class` from TSLint) | | | -| [`typescript/no-for-in-array`](./docs/rules/no-for-in-array.md) | Disallow iterating over an array with a for-in loop (`no-for-in-array` from TSLint) - | | | +| [`typescript/no-for-in-array`](./docs/rules/no-for-in-array.md) | Disallow iterating over an array with a for-in loop (`no-for-in-array` from TSLint) | | | | [`@typescript-eslint/no-inferrable-types`](./docs/rules/no-inferrable-types.md) | Disallows explicit type declarations for variables or parameters initialized to a number, string, or boolean. (`no-inferrable-types` from TSLint) | :heavy_check_mark: | :wrench: | | [`@typescript-eslint/no-misused-new`](./docs/rules/no-misused-new.md) | Enforce valid definition of `new` and `constructor`. (`no-misused-new` from TSLint) | :heavy_check_mark: | | | [`@typescript-eslint/no-namespace`](./docs/rules/no-namespace.md) | Disallow the use of custom TypeScript modules and namespaces (`no-namespace` from TSLint) | :heavy_check_mark: | | From 56fa66ee56ba3c657106dfdc7828924e8aa18842 Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Mon, 4 Feb 2019 13:16:57 -0500 Subject: [PATCH 4/5] Update roadmap --- packages/eslint-plugin/ROADMAP.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/packages/eslint-plugin/ROADMAP.md b/packages/eslint-plugin/ROADMAP.md index 20c3222089f5..c75debcb45ef 100644 --- a/packages/eslint-plugin/ROADMAP.md +++ b/packages/eslint-plugin/ROADMAP.md @@ -1,10 +1,15 @@ ο»Ώ# Roadmap -βœ… (28) = done -🌟 (79) = in ESLint core -πŸ”Œ (33) = in another plugin -πŸŒ“ (16) = implementations differ or ESLint version is missing functionality -πŸ›‘ (71) = unimplemented + + +βœ… (30) = done
+🌟 (79) = in ESLint core
+πŸ”Œ (33) = in another plugin
+πŸŒ“ (16) = implementations differ or ESLint version is missing functionality
+πŸ›‘ (68) = unimplemented
## TSLint rules From d5323342e569f4ca93904e95d5d302edaf7ea619 Mon Sep 17 00:00:00 2001 From: Benjamin Lichtman Date: Mon, 4 Feb 2019 17:12:56 -0800 Subject: [PATCH 5/5] fix: respond to review --- packages/eslint-plugin/README.md | 2 +- packages/eslint-plugin/ROADMAP.md | 4 ++-- .../eslint-plugin/docs/rules/no-for-in-array.md | 16 ++++++++++++---- packages/eslint-plugin/jsconfig.json | 8 -------- .../eslint-plugin/lib/rules/no-for-in-array.js | 11 +++++------ .../tests/lib/rules/no-for-in-array.js | 10 ++-------- 6 files changed, 22 insertions(+), 29 deletions(-) delete mode 100644 packages/eslint-plugin/jsconfig.json diff --git a/packages/eslint-plugin/README.md b/packages/eslint-plugin/README.md index 8f93b37f0c96..3807877a073e 100644 --- a/packages/eslint-plugin/README.md +++ b/packages/eslint-plugin/README.md @@ -128,7 +128,7 @@ Then you should add `airbnb` (or `airbnb-base`) to your `extends` section of `.e | [`@typescript-eslint/no-empty-interface`](./docs/rules/no-empty-interface.md) | Disallow the declaration of empty interfaces (`no-empty-interface` from TSLint) | :heavy_check_mark: | | | [`@typescript-eslint/no-explicit-any`](./docs/rules/no-explicit-any.md) | Disallow usage of the `any` type (`no-any` from TSLint) | :heavy_check_mark: | | | [`@typescript-eslint/no-extraneous-class`](./docs/rules/no-extraneous-class.md) | Forbids the use of classes as namespaces (`no-unnecessary-class` from TSLint) | | | -| [`typescript/no-for-in-array`](./docs/rules/no-for-in-array.md) | Disallow iterating over an array with a for-in loop (`no-for-in-array` from TSLint) | | | +| [`@typescript-eslint/no-for-in-array`](./docs/rules/no-for-in-array.md) | Disallow iterating over an array with a for-in loop (`no-for-in-array` from TSLint) | | | | [`@typescript-eslint/no-inferrable-types`](./docs/rules/no-inferrable-types.md) | Disallows explicit type declarations for variables or parameters initialized to a number, string, or boolean. (`no-inferrable-types` from TSLint) | :heavy_check_mark: | :wrench: | | [`@typescript-eslint/no-misused-new`](./docs/rules/no-misused-new.md) | Enforce valid definition of `new` and `constructor`. (`no-misused-new` from TSLint) | :heavy_check_mark: | | | [`@typescript-eslint/no-namespace`](./docs/rules/no-namespace.md) | Disallow the use of custom TypeScript modules and namespaces (`no-namespace` from TSLint) | :heavy_check_mark: | | diff --git a/packages/eslint-plugin/ROADMAP.md b/packages/eslint-plugin/ROADMAP.md index c75debcb45ef..5abf9e26d4ef 100644 --- a/packages/eslint-plugin/ROADMAP.md +++ b/packages/eslint-plugin/ROADMAP.md @@ -64,8 +64,7 @@ | [`no-empty`] | 🌟 | [`no-empty`][no-empty] | | [`no-eval`] | 🌟 | [`no-eval`][no-eval] | | [`no-floating-promises`] | πŸ›‘ | N/A ([relevant plugin][plugin:promise]) | -| [`no-for-in-array`] | βœ… | [`typescript/no-for-in-array`] | -| [`no-for-in-array`] | πŸ›‘ | N/A | +| [`no-for-in-array`] | βœ… | [`@typescript-eslint/no-for-in-array`] | | [`no-implicit-dependencies`] | πŸ”Œ | [`import/no-extraneous-dependencies`] | | [`no-inferred-empty-object-type`] | πŸ›‘ | N/A | | [`no-invalid-template-strings`] | 🌟 | [`no-template-curly-in-string`][no-template-curly-in-string] | @@ -592,6 +591,7 @@ Relevant plugins: [`chai-expect-keywords`](https://github.com/gavinaiken/eslint- [`@typescript-eslint/member-delimiter-style`]: https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/member-delimiter-style.md [`@typescript-eslint/prefer-interface`]: https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/prefer-interface.md [`@typescript-eslint/no-array-constructor`]: https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-array-constructor.md +[`@typescript-eslint/no-for-in-array`]: https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-for-in-array.md diff --git a/packages/eslint-plugin/docs/rules/no-for-in-array.md b/packages/eslint-plugin/docs/rules/no-for-in-array.md index 89aed236bac2..3a1cf2bdd370 100644 --- a/packages/eslint-plugin/docs/rules/no-for-in-array.md +++ b/packages/eslint-plugin/docs/rules/no-for-in-array.md @@ -6,10 +6,18 @@ This rule prohibits iterating over an array with a for-in loop. Rationale from TSLint: -> A for-in loop (for (var k in o)) iterates over the properties of an Object. -> While it is legal to use for-in loops with array types, it is not common. for-in will iterate over the indices of the array as strings, omitting any β€œholes” in the array. -> More common is to use for-of, which iterates over the values of an array. If you want to iterate over the indices, alternatives include: -> array.forEach((value, index) => { … }); for (const [index, value] of array.entries()) { … } for (let i = 0; i < array.length; i++) { … } +A for-in loop (`for (var k in o)`) iterates over the properties of an Object. +While it is legal to use for-in loops with array types, it is not common. +for-in will iterate over the indices of the array as strings, omitting any "holes" in +the array. +More common is to use for-of, which iterates over the values of an array. +If you want to iterate over the indices, alternatives include: + +```js +array.forEach((value, index) => { ... }); +for (const [index, value] of array.entries()) { ... } +for (let i = 0; i < array.length; i++) { ... } +``` Examples of **incorrect** code for this rule: diff --git a/packages/eslint-plugin/jsconfig.json b/packages/eslint-plugin/jsconfig.json deleted file mode 100644 index d68b67d6e404..000000000000 --- a/packages/eslint-plugin/jsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "compilerOptions": { - "target": "es2015", - "checkJs": true, - "strict": true, - "module": "commonjs" - } -} diff --git a/packages/eslint-plugin/lib/rules/no-for-in-array.js b/packages/eslint-plugin/lib/rules/no-for-in-array.js index 3d8e9ad00eff..23a19732ac45 100644 --- a/packages/eslint-plugin/lib/rules/no-for-in-array.js +++ b/packages/eslint-plugin/lib/rules/no-for-in-array.js @@ -23,6 +23,10 @@ module.exports = { url: util.metaDocsUrl('no-for-in-array') }, fixable: null, + messages: { + forInViolation: + 'For-in loops over arrays are forbidden. Use for-of or array.forEach instead.' + }, schema: [], type: 'problem' }, @@ -34,10 +38,6 @@ module.exports = { const checker = parserServices.program.getTypeChecker(); const originalNode = parserServices.esTreeNodeToTSNodeMap.get(node); - if (!originalNode) { - return; - } - const type = checker.getTypeAtLocation(originalNode.expression); if ( @@ -47,8 +47,7 @@ module.exports = { ) { context.report({ node, - message: - 'For-in loops over arrays are forbidden. Use for-of or array.forEach instead.' + messageId: 'forInViolation' }); } } diff --git a/packages/eslint-plugin/tests/lib/rules/no-for-in-array.js b/packages/eslint-plugin/tests/lib/rules/no-for-in-array.js index 94a3200608a4..91984453000d 100644 --- a/packages/eslint-plugin/tests/lib/rules/no-for-in-array.js +++ b/packages/eslint-plugin/tests/lib/rules/no-for-in-array.js @@ -16,10 +16,6 @@ const rule = require('../../../lib/rules/no-for-in-array'), // Tests //------------------------------------------------------------------------------ -// RuleTester.it = function(text, method) { -// return method.call({ break: true }); -// }; - const rootDir = path.join(process.cwd(), 'tests/fixtures/'); const parserOptions = { ecmaVersion: 2015, @@ -30,8 +26,6 @@ const ruleTester = new RuleTester({ parserOptions, parser: '@typescript-eslint/parser' }); -const message = - 'For-in loops over arrays are forbidden. Use for-of or array.forEach instead.'; ruleTester.run('no-for-in-array', rule, { valid: [ @@ -53,7 +47,7 @@ for (const x in [3, 4, 5]) { }`, errors: [ { - message, + messageId: 'forInViolation', type: 'ForInStatement' } ] @@ -66,7 +60,7 @@ for (const x in z) { }`, errors: [ { - message, + messageId: 'forInViolation', type: 'ForInStatement' } ] pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy