diff --git a/packages/eslint-plugin/docs/rules/no-magic-numbers.md b/packages/eslint-plugin/docs/rules/no-magic-numbers.md index 2e6fbfb7cfd..2ff5aab519d 100644 --- a/packages/eslint-plugin/docs/rules/no-magic-numbers.md +++ b/packages/eslint-plugin/docs/rules/no-magic-numbers.md @@ -1,58 +1,15 @@ -# Disallow Magic Numbers (no-magic-numbers) +# Disallow Magic Numbers (@typescript-eslint/no-magic-numbers) -'Magic numbers' are numbers that occur multiple time in code without an explicit meaning. +'Magic numbers' are numbers that occur multiple times in code without an explicit meaning. They should preferably be replaced by named constants. -```js -var now = Date.now(), - inOneHour = now + 60 * 60 * 1000; -``` - ## Rule Details -The `no-magic-numbers` rule aims to make code more readable and refactoring easier by ensuring that special numbers -are declared as constants to make their meaning explicit. - -**_This rule was taken from the ESLint core rule `no-magic-numbers`._** -**_Available options and test cases may vary depending on the version of ESLint installed in the system._** - -Examples of **incorrect** code for this rule: - -```js -/*eslint no-magic-numbers: "error"*/ - -var dutyFreePrice = 100, - finalPrice = dutyFreePrice + dutyFreePrice * 0.25; -``` +The `@typescript-eslint/no-magic-numbers` rule extends the `no-magic-numbers` rule from ESLint core, and adds support for handling Typescript specific code that would otherwise trigger the rule. -```js -/*eslint no-magic-numbers: "error"*/ +See the [ESLint documentation](https://eslint.org/docs/rules/no-magic-numbers) for more details on the `no-magic-numbers` rule. -var data = ['foo', 'bar', 'baz']; - -var dataLast = data[2]; -``` - -```js -/*eslint no-magic-numbers: "error"*/ - -var SECONDS; - -SECONDS = 60; -``` - -Examples of **correct** code for this rule: - -```js -/*eslint no-magic-numbers: "error"*/ - -var TAX = 0.25; - -var dutyFreePrice = 100, - finalPrice = dutyFreePrice + dutyFreePrice * TAX; -``` - -## Options +## Rule Changes ```cjson { @@ -62,79 +19,7 @@ var dutyFreePrice = 100, } ``` -### ignore - -An array of numbers to ignore. It's set to `[]` by default. -If provided, it must be an `Array`. - -Examples of **correct** code for the sample `{ "ignore": [1] }` option: - -```js -/*eslint no-magic-numbers: ["error", { "ignore": [1] }]*/ - -var data = ['foo', 'bar', 'baz']; -var dataLast = data.length && data[data.length - 1]; -``` - -### ignoreArrayIndexes - -A boolean to specify if numbers used as array indexes are considered okay. `false` by default. - -Examples of **correct** code for the `{ "ignoreArrayIndexes": true }` option: - -```js -/*eslint no-magic-numbers: ["error", { "ignoreArrayIndexes": true }]*/ - -var data = ['foo', 'bar', 'baz']; -var dataLast = data[2]; -``` - -### enforceConst - -A boolean to specify if we should check for the const keyword in variable declaration of numbers. `false` by default. - -Examples of **incorrect** code for the `{ "enforceConst": true }` option: - -```js -/*eslint no-magic-numbers: ["error", { "enforceConst": true }]*/ - -var TAX = 0.25; - -var dutyFreePrice = 100, - finalPrice = dutyFreePrice + dutyFreePrice * TAX; -``` - -### detectObjects - -A boolean to specify if we should detect numbers when setting object properties for example. `false` by default. - -Examples of **incorrect** code for the `{ "detectObjects": true }` option: - -```js -/*eslint no-magic-numbers: ["error", { "detectObjects": true }]*/ - -var magic = { - tax: 0.25, -}; - -var dutyFreePrice = 100, - finalPrice = dutyFreePrice + dutyFreePrice * magic.tax; -``` - -Examples of **correct** code for the `{ "detectObjects": true }` option: - -```js -/*eslint no-magic-numbers: ["error", { "detectObjects": true }]*/ - -var TAX = 0.25; - -var magic = { - tax: TAX, -}; - -var dutyFreePrice = 100, - finalPrice = dutyFreePrice + dutyFreePrice * magic.tax; -``` +In addition to the options supported by the `no-magic-numbers` rule in ESLint core, the rule adds the following options: ### ignoreNumericLiteralTypes @@ -143,7 +28,7 @@ A boolean to specify if numbers used in Typescript numeric literal types are con Examples of **incorrect** code for the `{ "ignoreNumericLiteralTypes": false }` option: ```ts -/*eslint no-magic-numbers: ["error", { "ignoreNumericLiteralTypes": false }]*/ +/*eslint @typescript-eslint/no-magic-numbers: ["error", { "ignoreNumericLiteralTypes": false }]*/ type SmallPrimes = 2 | 3 | 5 | 7 | 11; ``` @@ -151,7 +36,7 @@ type SmallPrimes = 2 | 3 | 5 | 7 | 11; Examples of **correct** code for the `{ "ignoreNumericLiteralTypes": true }` option: ```ts -/*eslint no-magic-numbers: ["error", { "ignoreNumericLiteralTypes": true }]*/ +/*eslint @typescript-eslint/no-magic-numbers: ["error", { "ignoreNumericLiteralTypes": true }]*/ type SmallPrimes = 2 | 3 | 5 | 7 | 11; ``` diff --git a/packages/eslint-plugin/src/rules/no-magic-numbers.ts b/packages/eslint-plugin/src/rules/no-magic-numbers.ts index 9421e39ba21..849bcf57bbb 100644 --- a/packages/eslint-plugin/src/rules/no-magic-numbers.ts +++ b/packages/eslint-plugin/src/rules/no-magic-numbers.ts @@ -11,15 +11,13 @@ import { JSONSchema4 } from 'json-schema'; type Options = util.InferOptionsTypeFromRule; type MessageIds = util.InferMessageIdsTypeFromRule; -// Original schema properties from the base rule -const { properties } = (baseRule.meta.schema as JSONSchema4[])[0]; - // Extend base schema with additional property to ignore TS numeric literal types -if (properties) { - properties.ignoreNumericLiteralTypes = { +const properties = { + ...(baseRule.meta.schema as JSONSchema4[])[0].properties, + ignoreNumericLiteralTypes: { type: 'boolean', - }; -} + }, +}; export default util.createRule({ name: 'no-magic-numbers', @@ -30,7 +28,7 @@ export default util.createRule({ category: 'Best Practices', recommended: false, }, - schema: baseRule.meta.schema, + schema: { ...baseRule.meta.schema, ...properties }, messages: baseRule.meta.messages, }, defaultOptions: [ @@ -62,7 +60,7 @@ export default util.createRule({ */ function isGrandparentTSTypeAliasDeclaration(node: TSESTree.Node): boolean { return node.parent && node.parent.parent - ? AST_NODE_TYPES.TSTypeAliasDeclaration === node.parent.parent.type + ? node.parent.parent.type === AST_NODE_TYPES.TSTypeAliasDeclaration : false; } @@ -76,7 +74,7 @@ export default util.createRule({ if ( node.parent && node.parent.parent && - AST_NODE_TYPES.TSUnionType === node.parent.parent.type + node.parent.parent.type === AST_NODE_TYPES.TSUnionType ) { return isGrandparentTSTypeAliasDeclaration(node.parent); } @@ -92,7 +90,7 @@ export default util.createRule({ */ function isParentTSLiteralType(node: TSESTree.Node): boolean { return node.parent - ? AST_NODE_TYPES.TSLiteralType === node.parent.type + ? node.parent.type === AST_NODE_TYPES.TSLiteralType : false; }