From 5346b5bbdbba81439ba761c282ba9cdcec7b45c8 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Tue, 14 Feb 2023 19:26:44 -0500 Subject: [PATCH] feat(eslint-plugin): rework configs: recommended, strict, stylistic; -type-checked (#5251) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat\!: include lesser configs in recommended/strict * Instead of nested includes, just go with flat * Fix configs test too * fix(utils): removed `TRuleListener` generic from the `createRule` (#5036) * refactor(utils)!: removed `TRuleListener` generic from the `createRule` * refactor!: removed `TRuleListener` generic from the `CLIEngine` and `RuleCreateFunction` * chore: document and refactor 'extra' to 'parserSettings' (#5834) * chore(website): fix renamed Sponsorship docs link (#5882) * docs: Mention wide globs performance implications in monorepos docs and parser README (#5864) * docs: Mention wide globs performance implications in monorepos docs and parser readme * Update docs/linting/typed-linting/MONOREPOS.md Co-authored-by: Josh Goldberg Co-authored-by: Josh Goldberg Co-authored-by: Adnan Hashmi <56730784+adnanhashmi09@users.noreply.github.com> * feat: create TSTypeQuery node when TSImportType has isTypeOf (#3076) * feat: update TSImportType node * fix: update visitor keys * chore: document and refactor 'extra' to 'parserSettings' (#5834) * chore(website): fix renamed Sponsorship docs link (#5882) * docs: Mention wide globs performance implications in monorepos docs and parser README (#5864) * docs: Mention wide globs performance implications in monorepos docs and parser readme * Update docs/linting/typed-linting/MONOREPOS.md Co-authored-by: Josh Goldberg Co-authored-by: Josh Goldberg Co-authored-by: Adnan Hashmi <56730784+adnanhashmi09@users.noreply.github.com> * feat(scope-manager): ignore ECMA version (#5889) * feat(scope-manager): ignore ECMA version * chore: document and refactor 'extra' to 'parserSettings' (#5834) * chore(website): fix renamed Sponsorship docs link (#5882) * Remove much more * Fix WebLinter lint * docs: Mention wide globs performance implications in monorepos docs and parser README (#5864) * docs: Mention wide globs performance implications in monorepos docs and parser readme * Update docs/linting/typed-linting/MONOREPOS.md Co-authored-by: Josh Goldberg * chore: add auto-canary release for v6 (#5883) Co-authored-by: Adnan Hashmi <56730784+adnanhashmi09@users.noreply.github.com> * feat: remove semantically invalid properties from TSEnumDeclaration, TSInterfaceDeclaration and TSModuleDeclaration (#4863) * chore: remove invalid properties from ast nodes * chore: remove invalid code in scope-manager and typescript-estree * chore: re-write snapshots that were using invalid properties * feat: remove modifiers union from ast types Co-authored-by: Juan GarcΓ­a Co-authored-by: Josh Goldberg * fix(eslint-plugin): remove valid-typeof disable in eslint-recommended (#5381) * feat(utils): remove (ts-)eslint-scope types (#5256) * chore(utils)\!: remove (ts-)eslint-scope types * Remove eslint-scope dep * More file deletions * fix(eslint-plugin): [explicit-module-boundary-types] remove shouldTrackReferences option from schema (#5399) * Enabled base config * The script runs now * Upgraded ts-node to avoid bug * Updated configuration docs * Updated configs exports * Updated generation script * Revert CHANGELOG.md change * Switch to ts-node/esm loader * Fix post-merge type failure * pin ts-node to 10.9.0 * Switch to tsx for all but Docusaurus * Fix post-merge generate-breaking-changes issues * Switched generation to explicitly include lesser rules * Include recommended in strict * More granular caching in prepare-install/action.yml * Fix type checking issues with generate-configs.mts * Adjusted docs, tests, and RulesTable * Adjusted rule docs pages and more RulesTable fixes * Swap πŸ’… to 🎨 * pin ts-node to 10.7.0 * Fix docs post-merge artifact * Err, mostly or completely fix * prefer-reduce-type-parameter back to strict; fix other complaints * Put integration test back * Start updating the snapshot * More snapshot correction * Put no-unused-vars in recommended * Fix root config to always error; remove unneeded no-unused-vars * Some more linting * Undo action.yml changes * Added todo * Fix no-extra-semi.ts and configs.test.ts * Merge branch 'v6' * Update packages/eslint-plugin/tools/generate-configs.mts Co-authored-by: Brad Zacher * Last few review fixups * lil 'a' typo * No more .mts needed * Adjust eslint-plugin/tools/generate files to build * Fix casing * ...and extensions * git mv for casing * Simplify old recommended-requiring-type-checking include; delete file --------- Co-authored-by: Mateusz BurzyΕ„ski Co-authored-by: Adnan Hashmi <56730784+adnanhashmi09@users.noreply.github.com> Co-authored-by: Armano Co-authored-by: Juan GarcΓ­a <82288753+juank1809@users.noreply.github.com> Co-authored-by: Juan GarcΓ­a Co-authored-by: Brad Zacher --- .eslintrc.js | 18 +- docs/Custom_Rules.mdx | 2 - docs/linting/CONFIGURATIONS.mdx | 141 ------ docs/linting/Configurations.mdx | 208 ++++++++ docs/linting/Typed_Linting.mdx | 4 +- docs/linting/typed-linting/Monorepos.mdx | 4 +- .../src/rules/no-poorly-typed-ts-props.ts | 2 +- .../src/rules/no-typescript-default-import.ts | 2 +- .../src/rules/no-typescript-estree-import.ts | 2 +- .../src/rules/plugin-test-formatting.ts | 2 +- .../src/rules/prefer-ast-types-enum.ts | 2 +- .../eslint-plugin-tslint/src/rules/config.ts | 1 - packages/eslint-plugin/src/configs/all.ts | 5 +- packages/eslint-plugin/src/configs/base.ts | 5 +- .../recommended-requiring-type-checking.ts | 26 - .../src/configs/recommended-type-checked.ts | 47 ++ .../eslint-plugin/src/configs/recommended.ts | 18 +- .../src/configs/strict-type-checked.ts | 69 +++ packages/eslint-plugin/src/configs/strict.ts | 70 ++- .../src/configs/stylistic-type-checked.ts | 35 ++ .../eslint-plugin/src/configs/stylistic.ts | 30 ++ packages/eslint-plugin/src/index.ts | 15 +- .../src/rules/adjacent-overload-signatures.ts | 2 +- .../eslint-plugin/src/rules/array-type.ts | 2 +- .../eslint-plugin/src/rules/await-thenable.ts | 2 +- .../eslint-plugin/src/rules/ban-ts-comment.ts | 2 +- .../src/rules/ban-tslint-comment.ts | 2 +- packages/eslint-plugin/src/rules/ban-types.ts | 2 +- .../eslint-plugin/src/rules/block-spacing.ts | 1 - .../eslint-plugin/src/rules/brace-style.ts | 1 - .../src/rules/class-literal-property-style.ts | 2 +- .../eslint-plugin/src/rules/comma-dangle.ts | 1 - .../eslint-plugin/src/rules/comma-spacing.ts | 1 - .../rules/consistent-generic-constructors.ts | 2 +- .../rules/consistent-indexed-object-style.ts | 2 +- .../src/rules/consistent-type-assertions.ts | 2 +- .../src/rules/consistent-type-definitions.ts | 2 +- .../src/rules/consistent-type-exports.ts | 1 - .../src/rules/consistent-type-imports.ts | 1 - .../src/rules/default-param-last.ts | 1 - .../eslint-plugin/src/rules/dot-notation.ts | 2 +- .../rules/explicit-function-return-type.ts | 1 - .../rules/explicit-member-accessibility.ts | 1 - .../rules/explicit-module-boundary-types.ts | 1 - .../src/rules/func-call-spacing.ts | 1 - packages/eslint-plugin/src/rules/indent.ts | 1 - .../src/rules/init-declarations.ts | 1 - .../eslint-plugin/src/rules/key-spacing.ts | 1 - .../src/rules/keyword-spacing.ts | 1 - .../src/rules/lines-between-class-members.ts | 1 - .../src/rules/member-delimiter-style.ts | 1 - .../src/rules/member-ordering.ts | 1 - .../src/rules/method-signature-style.ts | 1 - .../naming-convention-utils/parse-options.ts | 5 +- .../src/rules/naming-convention.ts | 1 - .../src/rules/no-array-constructor.ts | 2 +- .../rules/no-confusing-non-null-assertion.ts | 2 +- .../src/rules/no-confusing-void-expression.ts | 1 - .../src/rules/no-dupe-class-members.ts | 1 - .../src/rules/no-duplicate-enum-values.ts | 2 +- .../src/rules/no-empty-function.ts | 2 +- .../src/rules/no-empty-interface.ts | 2 +- .../src/rules/no-explicit-any.ts | 2 +- .../src/rules/no-extra-non-null-assertion.ts | 2 +- .../src/rules/no-extra-parens.ts | 1 - .../eslint-plugin/src/rules/no-extra-semi.ts | 1 - .../src/rules/no-floating-promises.ts | 2 +- .../src/rules/no-for-in-array.ts | 2 +- .../src/rules/no-implied-eval.ts | 2 +- .../src/rules/no-import-type-side-effects.ts | 1 - .../src/rules/no-inferrable-types.ts | 2 +- .../src/rules/no-invalid-this.ts | 1 - .../eslint-plugin/src/rules/no-loop-func.ts | 1 - .../src/rules/no-loss-of-precision.ts | 2 +- .../src/rules/no-magic-numbers.ts | 1 - .../eslint-plugin/src/rules/no-misused-new.ts | 2 +- .../src/rules/no-misused-promises.ts | 2 +- .../eslint-plugin/src/rules/no-namespace.ts | 2 +- .../no-non-null-asserted-optional-chain.ts | 2 +- .../src/rules/no-non-null-assertion.ts | 2 +- .../eslint-plugin/src/rules/no-redeclare.ts | 1 - .../rules/no-redundant-type-constituents.ts | 1 - .../src/rules/no-require-imports.ts | 1 - .../src/rules/no-restricted-imports.ts | 1 - packages/eslint-plugin/src/rules/no-shadow.ts | 1 - .../eslint-plugin/src/rules/no-this-alias.ts | 2 +- .../eslint-plugin/src/rules/no-type-alias.ts | 1 - .../src/rules/no-unnecessary-qualifier.ts | 1 - .../rules/no-unnecessary-type-assertion.ts | 2 +- .../rules/no-unnecessary-type-constraint.ts | 2 +- .../src/rules/no-unsafe-argument.ts | 2 +- .../src/rules/no-unsafe-assignment.ts | 2 +- .../eslint-plugin/src/rules/no-unsafe-call.ts | 2 +- .../src/rules/no-unsafe-member-access.ts | 2 +- .../src/rules/no-unsafe-return.ts | 2 +- .../src/rules/no-unused-expressions.ts | 1 - .../eslint-plugin/src/rules/no-unused-vars.ts | 2 +- .../src/rules/no-use-before-define.ts | 1 - .../src/rules/no-useless-empty-export.ts | 1 - .../src/rules/no-var-requires.ts | 2 +- .../non-nullable-type-assertion-style.ts | 2 +- .../src/rules/object-curly-spacing.ts | 1 - .../rules/padding-line-between-statements.ts | 1 - .../src/rules/parameter-properties.ts | 1 - .../src/rules/prefer-as-const.ts | 2 +- .../src/rules/prefer-enum-initializers.ts | 1 - .../eslint-plugin/src/rules/prefer-for-of.ts | 2 +- .../src/rules/prefer-function-type.ts | 2 +- .../src/rules/prefer-namespace-keyword.ts | 2 +- .../src/rules/prefer-nullish-coalescing.ts | 2 +- .../src/rules/prefer-optional-chain.ts | 2 +- .../rules/prefer-readonly-parameter-types.ts | 1 - .../src/rules/prefer-readonly.ts | 1 - .../src/rules/prefer-regexp-exec.ts | 1 - .../rules/prefer-string-starts-ends-with.ts | 2 +- .../src/rules/promise-function-async.ts | 1 - packages/eslint-plugin/src/rules/quotes.ts | 1 - .../src/rules/require-array-sort-compare.ts | 1 - .../eslint-plugin/src/rules/require-await.ts | 2 +- .../src/rules/restrict-plus-operands.ts | 2 +- .../rules/restrict-template-expressions.ts | 2 +- .../eslint-plugin/src/rules/return-await.ts | 1 - packages/eslint-plugin/src/rules/semi.ts | 1 - .../src/rules/sort-type-constituents.ts | 2 +- .../src/rules/space-before-blocks.ts | 1 - .../src/rules/space-before-function-paren.ts | 1 - .../src/rules/space-infix-ops.ts | 1 - .../src/rules/strict-boolean-expressions.ts | 1 - .../src/rules/switch-exhaustiveness-check.ts | 1 - .../src/rules/triple-slash-reference.ts | 2 +- .../src/rules/type-annotation-spacing.ts | 1 - packages/eslint-plugin/src/rules/typedef.ts | 1 - .../eslint-plugin/src/rules/unbound-method.ts | 2 +- packages/eslint-plugin/tests/configs.test.ts | 165 +++++-- packages/eslint-plugin/tests/index.test.ts | 6 +- .../tests/util/getWrappingFixer.test.ts | 1 - .../tests/util/isNodeEqual.test.ts | 1 - .../tools/generate-breaking-changes.ts | 136 +++--- .../eslint-plugin/tools/generate-configs.ts | 450 +++++++++--------- packages/typescript-estree/src/parser.ts | 1 - .../src/ts-estree/ts-nodes.ts | 2 - packages/utils/src/ts-eslint/Rule.ts | 4 +- .../tests/eslint-utils/RuleCreator.test.ts | 4 +- .../website/plugins/generated-rule-docs.ts | 5 +- .../src/components/RulesTable/index.tsx | 123 +++-- .../components/RulesTable/styles.module.css | 11 + .../editor/createProvideCodeActions.ts | 1 - .../theme/MDXComponents/RuleAttributes.tsx | 18 +- ...nded-does-not-require-program.test.ts.snap | 41 +- yarn.lock | 6 +- 150 files changed, 1038 insertions(+), 813 deletions(-) delete mode 100644 docs/linting/CONFIGURATIONS.mdx create mode 100644 docs/linting/Configurations.mdx delete mode 100644 packages/eslint-plugin/src/configs/recommended-requiring-type-checking.ts create mode 100644 packages/eslint-plugin/src/configs/recommended-type-checked.ts create mode 100644 packages/eslint-plugin/src/configs/strict-type-checked.ts create mode 100644 packages/eslint-plugin/src/configs/stylistic-type-checked.ts create mode 100644 packages/eslint-plugin/src/configs/stylistic.ts diff --git a/.eslintrc.js b/.eslintrc.js index 99f3f5d3e41..7c186be418d 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -17,8 +17,8 @@ module.exports = { extends: [ 'eslint:recommended', 'plugin:eslint-plugin/recommended', - 'plugin:@typescript-eslint/recommended', - 'plugin:@typescript-eslint/recommended-requiring-type-checking', + 'plugin:@typescript-eslint/recommended-type-checked', + // TODO: consider enabling strict-type-checked and/or stylistic-type-checked ], parserOptions: { sourceType: 'module', @@ -94,7 +94,7 @@ module.exports = { }, ], '@typescript-eslint/no-unused-vars': [ - 'warn', + 'error', { varsIgnorePattern: '^_', argsIgnorePattern: '^_' }, ], @@ -122,7 +122,7 @@ module.exports = { 'no-console': 'error', 'no-process-exit': 'error', 'no-fallthrough': [ - 'warn', + 'error', { commentPattern: '.*intentional fallthrough.*' }, ], @@ -223,7 +223,7 @@ module.exports = { '@typescript-eslint/no-unsafe-member-access': 'off', '@typescript-eslint/no-unsafe-return': 'off', 'eslint-plugin/consistent-output': 'off', // Might eventually be removed from `eslint-plugin/recommended`: https://github.com/not-an-aardvark/eslint-plugin-eslint-plugin/issues/284 - 'jest/no-disabled-tests': 'warn', + 'jest/no-disabled-tests': 'error', 'jest/no-focused-tests': 'error', 'jest/no-alias-methods': 'error', 'jest/no-identical-title': 'error', @@ -231,9 +231,9 @@ module.exports = { 'jest/no-test-prefixes': 'error', 'jest/no-done-callback': 'error', 'jest/no-test-return-statement': 'error', - 'jest/prefer-to-be': 'warn', - 'jest/prefer-to-contain': 'warn', - 'jest/prefer-to-have-length': 'warn', + 'jest/prefer-to-be': 'error', + 'jest/prefer-to-contain': 'error', + 'jest/prefer-to-have-length': 'error', 'jest/prefer-spy-on': 'error', 'jest/valid-expect': 'error', 'jest/no-deprecated-functions': 'error', @@ -312,7 +312,7 @@ module.exports = { }, // tools and tests { - files: ['**/tools/**/*.ts', '**/tests/**/*.ts'], + files: ['**/tools/**/*.*t*', '**/tests/**/*.ts'], rules: { // allow console logs in tools and tests 'no-console': 'off', diff --git a/docs/Custom_Rules.mdx b/docs/Custom_Rules.mdx index cce54c78ad6..ca471e03395 100644 --- a/docs/Custom_Rules.mdx +++ b/docs/Custom_Rules.mdx @@ -63,7 +63,6 @@ export const rule = createRule({ docs: { description: 'Function declaration names should start with an upper-case letter.', - recommended: 'warn', }, messages: { uppercase: 'Start this name with an upper-case letter.', @@ -256,7 +255,6 @@ export const rule = createRule({ meta: { docs: { description: 'Avoid looping over enums.', - recommended: 'error', }, messages: { loopOverEnum: 'Do not loop over enums.', diff --git a/docs/linting/CONFIGURATIONS.mdx b/docs/linting/CONFIGURATIONS.mdx deleted file mode 100644 index 10d3f6293d5..00000000000 --- a/docs/linting/CONFIGURATIONS.mdx +++ /dev/null @@ -1,141 +0,0 @@ ---- -id: configs -title: Configurations ---- - -[ESLint shareable configurations](https://eslint.org/docs/latest/developer-guide/shareable-configs) exist to provide a comprehensive base config for you. -`@typescript-eslint/eslint-plugin` includes built-in configurations you can extend from to pull in the recommended starting rules. - -> With the exception of `strict`, all configurations are considered "stable". -> Rule additions and removals are treated as breaking changes and will only be done in major version bumps. - -## Recommended Configurations - -Most projects should extend from at least one of: - -- [`recommended`](#recommended): Recommended rules for code correctness that you can drop in without additional configuration. -- [`recommended-requiring-type-checking`](#recommended-requiring-type-checking): Additional recommended rules that require type information. -- [`strict`](#strict): Additional strict rules that can also catch bugs but are more opinionated than recommended rules. - -:::tip -We recommend most projects use [`recommended-requiring-type-checking`](#recommended-requiring-type-checking) (which requires [typed linting](./Typed_Linting.mdx)). -::: - -:::note -These configurations are our recommended starting points, but **you don't need to use them as-is**. -ESLint allows configuring own rule settings on top of extended configurations. -See [ESLint's Configuring Rules docs](https://eslint.org/docs/user-guide/configuring/rules#using-configuration-files). -::: - -### `recommended` - -Recommended rules for code correctness that you can drop in without additional configuration. -These rules are those whose reports are almost always for a bad practice and/or likely bug. -`recommended` also disables rules known to conflict with this repository, or cause issues in TypeScript codebases. - -```json -{ - "extends": ["plugin:@typescript-eslint/recommended"] -} -``` - -See [`configs/recommended.ts`](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/src/configs/recommended.ts) for the exact contents of this config. - -:::tip -We strongly recommend all TypeScript projects extend from `plugin:@typescript-eslint/recommended`. -::: - -### `recommended-requiring-type-checking` - -Additional recommended rules that require type information. -Rules in this configuration are similarly useful to those in `recommended`. - -```json -{ - "extends": [ - "plugin:@typescript-eslint/recommended", - "plugin:@typescript-eslint/recommended-requiring-type-checking" - ] -} -``` - -See [`configs/recommended-requiring-type-checking.ts`](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/src/configs/recommended-requiring-type-checking.ts) for the exact contents of this config. - -:::tip -We recommend all TypeScript projects extend from `plugin:@typescript-eslint/recommended-requiring-type-checking`, with the caveat that rules using type information take longer to run. -See [Linting with Type Information](/linting/typed-linting) for more details. -::: - -### `strict` - -Additional strict rules that can also catch bugs but are more opinionated than recommended rules. - -```json -{ - "extends": [ - "plugin:@typescript-eslint/recommended", - "plugin:@typescript-eslint/recommended-requiring-type-checking", - "plugin:@typescript-eslint/strict" - ] -} -``` - -See [`configs/strict.ts`](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/src/configs/strict.ts) for the exact contents of this config. - -:::caution -We recommend a TypeScript project extend from `plugin:@typescript-eslint/strict` only if a nontrivial percentage of its developers are highly proficient in TypeScript. -::: - -## Other Configurations - -typescript-eslint includes a scattering of utility configurations used by the recommended configurations. -We don't recommend using these directly; instead, extend from an earlier recommended rule. - -### `all` - -Enables each the rules provided as a part of typescript-eslint. -Note that many rules are not applicable in all codebases, or are meant to be configured. - -See [`configs/all.ts`](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/src/configs/all.ts) for the exact contents of this config. - -:::warning -We do not recommend a TypeScript projects extend from `plugin:@typescript-eslint/all`. -Many rules conflict with each other and/or are intended to be configured per-project. -::: - -### `base` - -A minimal ruleset that sets only the required parser and plugin options needed to run typescript-eslint. - - - -This config is automatically included if you use any of the recommended configurations. - -### `eslint-recommended` - -This ruleset is meant to be used after extending `eslint:recommended`. -It disables core ESLint rules that are already checked by the TypeScript compiler. -Additionally, it enables rules that promote using the more modern constructs TypeScript allows for. - -```jsonc -{ - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/eslint-recommended" - ] -} -``` - -This config is automatically included if you use any of the recommended configurations. - -See [`configs/eslint-recommended.ts`](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/src/configs/eslint-recommended.ts) for the exact contents of this config. - -## Suggesting Configuration Changes - -If you feel strongly that a specific rule should (or should not) be one of these configurations, please [file an issue](https://github.com/typescript-eslint/typescript-eslint/issues/new?assignees=&labels=package%3A+eslint-plugin%2Cpreset+config+change%2Ctriage&template=09-config-change.yaml&title=Configs%3A+%3Ca+short+description+of+my+proposal%3E) along with a **detailed** argument explaining your reasoning. - -## Formatting - -None of the preset configs provided by typescript-eslint enable formatting rules (rules that only serve to enforce code whitespace and other trivia). -We strongly recommend you use Prettier or an equivalent for formatting your code, not ESLint formatting rules. -See [What About Formatting? > Suggested Usage](./troubleshooting/formatting#suggested-usage). diff --git a/docs/linting/Configurations.mdx b/docs/linting/Configurations.mdx new file mode 100644 index 00000000000..3d56abb8af0 --- /dev/null +++ b/docs/linting/Configurations.mdx @@ -0,0 +1,208 @@ +--- +id: configs +title: Configurations +--- + +[ESLint shareable configurations](https://eslint.org/docs/latest/developer-guide/shareable-configs) exist to provide a comprehensive list of rules settings that you can start with. +`@typescript-eslint/eslint-plugin` includes built-in configurations you can extend from to pull in the recommended starting rules. + +> With the exception of `all`, `strict`, and `strict-type-checked`, all configurations are considered "stable". +> Rule additions and removals are treated as breaking changes and will only be done in major version bumps. + +## Getting Started + +### Projects Without Type Checking + +If your project does not enable [typed linting](./Typed_Linting.mdx), we suggest enabling the [`recommended`](#recommended) and [`stylistic`](#stylistic) configurations to start: + +```json +{ + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:@typescript-eslint/stylistic" + ] +} +``` + +> If a majority of developers working on your project are comfortable with TypeScript and typescript-eslint, consider replacing `recommended` with `strict`. + +### Projects With Type Checking + +If your project enables [typed linting](./Typed_Linting.mdx), we suggest enabling the [`recommended-type-checked`](#recommended-type-checked) and [`stylistic-type-checked`](#stylistic-type-checked) configurations to start: + +```json +{ + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended-type-checked", + "plugin:@typescript-eslint/stylistic-type-checked" + ] +} +``` + +> If a majority of developers working on your project are comfortable with TypeScript and typescript-eslint, consider replacing `recommended-type-checked` with `strict-type-checked`. + +## Recommended Configurations + +We recommend that most projects should extend from one of: + +- [`recommended`](#recommended): Recommended rules for code correctness that you can drop in without additional configuration. +- [`recommended-type-checked`](#recommended-type-checked): Additional recommended rules that require type information. +- [`strict`](#strict): Additional strict rules that can also catch bugs but are more opinionated than recommended rules. +- [`strict-type-checked`](#strict-type-checked): Additional strict rules require type information. + +Additionally, we provide a [`stylistic`](#stylistic) config that enforces concise and consistent code. +We recommend that most projects should extend from either: + +- [`stylistic`](#stylistic): Stylistic rules you can drop in without additional configuration. +- [`stylistic-type-checked`](#stylistic-type-checked): Additional stylistic rules that require type information. + +:::note +These configurations are our recommended starting points, but **you don't need to use them as-is**. +ESLint allows configuring own rule settings on top of extended configurations. +See [ESLint's Configuring Rules docs](https://eslint.org/docs/user-guide/configuring/rules#using-configuration-files). +::: + +### `recommended` + +Recommended rules for code correctness that you can drop in without additional configuration. +These rules are those whose reports are almost always for a bad practice and/or likely bug. +`recommended` also disables core ESLint rules known to conflict with typescript-eslint rules or cause issues in TypeScript codebases. + +```json +{ + "extends": ["plugin:@typescript-eslint/recommended"] +} +``` + +See [`configs/recommended.ts`](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/src/configs/recommended.ts) for the exact contents of this config. + +### `recommended-type-checked` + +Contains all of `recommended` along with additional recommended rules that require type information. +Rules newly added in this configuration are similarly useful to those in `recommended`. + +```json +{ + "extends": ["plugin:@typescript-eslint/recommended-type-checked"] +} +``` + +See [`configs/recommended-type-checked.ts`](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/src/configs/recommended-type-checked.ts) for the exact contents of this config. + +### `strict` + +Contains all of `recommended`, as well as additional strict rules that can also catch bugs. +Rules added in `strict` are more opinionated than recommended rules and might not apply to all projects. + +```json +{ + "extends": ["plugin:@typescript-eslint/strict"] +} +``` + +See [`configs/strict.ts`](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/src/configs/strict.ts) for the exact contents of this config. + +:::caution +We recommend a TypeScript project extend from `plugin:@typescript-eslint/strict` only if a nontrivial percentage of its developers are highly proficient in TypeScript. +::: + +### `strict-type-checked` + +Contains all of `recommended`, `recommended-type-checked`, and `strict`, along with additional strict rules that require type information. +Rules newly added in this configuration are similarly useful (and opinionated) to those in `strict`. + +```json +{ + "extends": ["plugin:@typescript-eslint/strict-type-checked"] +} +``` + +See [`configs/strict-type-checked.ts`](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/src/configs/strict-type-checked.ts) for the exact contents of this config. + +:::caution +We recommend a TypeScript project extend from `plugin:@typescript-eslint/strict-type-checked` only if a nontrivial percentage of its developers are highly proficient in TypeScript. +::: + +### `stylistic` + +Rules considered to be best practice for modern TypeScript codebases, but that do not impact program logic. +These rules are generally opinionated about enforcing simpler code patterns. + +```json +{ + "extends": ["plugin:@typescript-eslint/stylistic"] +} +``` + +See [`configs/stylistic.ts`](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/src/configs/stylistic.ts) for the exact contents of this config. + +### `stylistic-type-checked` + +Contains all of `stylistic`, along with additional stylistic rules that require type information. +Rules newly added in this configuration are similarly opinionated to those in `stylistic`. + +```json +{ + "extends": ["plugin:@typescript-eslint/stylistic-type-checked"] +} +``` + +See [`configs/stylistic-type-checked.ts`](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/src/configs/strict-type-checked.ts) for the exact contents of this config. + +## Other Configurations + +typescript-eslint includes a scattering of utility configurations used by the recommended configurations. +We don't recommend using these directly; instead, extend from an earlier recommended rule. + +### `all` + +Enables each the rules provided as a part of typescript-eslint. +Note that many rules are not applicable in all codebases, or are meant to be configured. + +See [`configs/all.ts`](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/src/configs/all.ts) for the exact contents of this config. + +:::warning +We do not recommend TypeScript projects extend from `plugin:@typescript-eslint/all`. +Many rules conflict with each other and/or are intended to be configured per-project. +::: + +### `base` + +A minimal ruleset that sets only the required parser and plugin options needed to run typescript-eslint. + + + +This config is automatically included if you use any of the recommended configurations. + +See [`configs/base.ts`](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/src/configs/base.ts) for the exact contents of this config. + +### `eslint-recommended` + +This ruleset is meant to be used after extending `eslint:recommended`. +It disables core ESLint rules that are already checked by the TypeScript compiler. +Additionally, it enables rules that promote using the more modern constructs TypeScript allows for. + +```jsonc +{ + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended" + ] +} +``` + +This config is automatically included if you use any of the recommended configurations. + +See [`configs/eslint-recommended.ts`](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/src/configs/eslint-recommended.ts) for the exact contents of this config. + +## Suggesting Configuration Changes + +If you feel strongly that a specific rule should (or should not) be one of these configurations, please [file an issue](https://github.com/typescript-eslint/typescript-eslint/issues/new?assignees=&labels=package%3A+eslint-plugin%2Cpreset+config+change%2Ctriage&template=09-config-change.yaml&title=Configs%3A+%3Ca+short+description+of+my+proposal%3E) along with a **detailed** argument explaining your reasoning. + +## Formatting + +None of the preset configs provided by typescript-eslint enable formatting rules (rules that only serve to enforce code whitespace and other trivia). +We strongly recommend you use Prettier or an equivalent for formatting your code, not ESLint formatting rules. +See [What About Formatting? > Suggested Usage](./troubleshooting/formatting#suggested-usage). diff --git a/docs/linting/Typed_Linting.mdx b/docs/linting/Typed_Linting.mdx index a51afdad02b..cadeabcde3c 100644 --- a/docs/linting/Typed_Linting.mdx +++ b/docs/linting/Typed_Linting.mdx @@ -12,7 +12,7 @@ module.exports = { 'eslint:recommended', 'plugin:@typescript-eslint/recommended', // Add this line - 'plugin:@typescript-eslint/recommended-requiring-type-checking', + 'plugin:@typescript-eslint/recommended-type-checked', ], plugins: ['@typescript-eslint'], parser: '@typescript-eslint/parser', @@ -28,7 +28,7 @@ module.exports = { In more detail: -- `plugin:@typescript-eslint/recommended-requiring-type-checking` is another [recommended configuration](./CONFIGURATIONS.mdx) we provide. This one contains recommended rules that additionally require type information. +- `plugin:@typescript-eslint/recommended-type-checked` is another [recommended configuration](./Configurations.mdx) we provide. This one contains recommended rules that additionally require type information. - `parserOptions.project` tells our parser the relative path where your project's `tsconfig.json` is. - If your project is a multi-package monorepo, see [our docs on configuring a monorepo](./typed-linting/Monorepos.mdx). - `parserOptions.tsconfigRootDir` tells our parser the absolute path of your project's root directory (see [Parser#tsconfigRootDir](../architecture/Parser.mdx#tsconfigRootDir)). diff --git a/docs/linting/typed-linting/Monorepos.mdx b/docs/linting/typed-linting/Monorepos.mdx index 9d0d67e331f..054639daa40 100644 --- a/docs/linting/typed-linting/Monorepos.mdx +++ b/docs/linting/typed-linting/Monorepos.mdx @@ -47,7 +47,7 @@ module.exports = { extends: [ 'eslint:recommended', 'plugin:@typescript-eslint/recommended', - 'plugin:@typescript-eslint/recommended-requiring-type-checking', + 'plugin:@typescript-eslint/recommended-type-checked', ], parser: '@typescript-eslint/parser', parserOptions: { @@ -72,7 +72,7 @@ module.exports = { extends: [ 'eslint:recommended', 'plugin:@typescript-eslint/recommended', - 'plugin:@typescript-eslint/recommended-requiring-type-checking', + 'plugin:@typescript-eslint/recommended-type-checked', ], parser: '@typescript-eslint/parser', parserOptions: { diff --git a/packages/eslint-plugin-internal/src/rules/no-poorly-typed-ts-props.ts b/packages/eslint-plugin-internal/src/rules/no-poorly-typed-ts-props.ts index a3b4a416021..7b34aa0fd26 100644 --- a/packages/eslint-plugin-internal/src/rules/no-poorly-typed-ts-props.ts +++ b/packages/eslint-plugin-internal/src/rules/no-poorly-typed-ts-props.ts @@ -36,7 +36,7 @@ export default createRule({ docs: { description: "Enforce that rules don't use TS API properties with known bad type definitions", - recommended: 'error', + recommended: 'recommended', requiresTypeChecking: true, }, fixable: 'code', diff --git a/packages/eslint-plugin-internal/src/rules/no-typescript-default-import.ts b/packages/eslint-plugin-internal/src/rules/no-typescript-default-import.ts index fd7279c3823..8c4676a32ad 100644 --- a/packages/eslint-plugin-internal/src/rules/no-typescript-default-import.ts +++ b/packages/eslint-plugin-internal/src/rules/no-typescript-default-import.ts @@ -21,7 +21,7 @@ export default createRule({ docs: { description: "Enforce that packages rules don't do `import ts from 'typescript';`", - recommended: 'error', + recommended: 'recommended', }, fixable: 'code', schema: [], diff --git a/packages/eslint-plugin-internal/src/rules/no-typescript-estree-import.ts b/packages/eslint-plugin-internal/src/rules/no-typescript-estree-import.ts index 28f7439472b..758328efe21 100644 --- a/packages/eslint-plugin-internal/src/rules/no-typescript-estree-import.ts +++ b/packages/eslint-plugin-internal/src/rules/no-typescript-estree-import.ts @@ -16,7 +16,7 @@ export default createRule({ type: 'problem', docs: { description: `Enforce that eslint-plugin rules don't require anything from ${TSESTREE_NAME} or ${TYPES_NAME}`, - recommended: 'error', + recommended: 'recommended', }, fixable: 'code', schema: [], diff --git a/packages/eslint-plugin-internal/src/rules/plugin-test-formatting.ts b/packages/eslint-plugin-internal/src/rules/plugin-test-formatting.ts index f9d36b29de9..32ab1d41df1 100644 --- a/packages/eslint-plugin-internal/src/rules/plugin-test-formatting.ts +++ b/packages/eslint-plugin-internal/src/rules/plugin-test-formatting.ts @@ -108,7 +108,7 @@ export default createRule({ type: 'problem', docs: { description: `Enforce that eslint-plugin test snippets are correctly formatted`, - recommended: 'error', + recommended: 'recommended', requiresTypeChecking: true, }, fixable: 'code', diff --git a/packages/eslint-plugin-internal/src/rules/prefer-ast-types-enum.ts b/packages/eslint-plugin-internal/src/rules/prefer-ast-types-enum.ts index 4099e2f02be..e042f328614 100755 --- a/packages/eslint-plugin-internal/src/rules/prefer-ast-types-enum.ts +++ b/packages/eslint-plugin-internal/src/rules/prefer-ast-types-enum.ts @@ -13,7 +13,7 @@ export default createRule({ meta: { type: 'problem', docs: { - recommended: 'error', + recommended: 'recommended', description: 'Enforce consistent usage of `AST_NODE_TYPES`, `AST_TOKEN_TYPES` and `DefinitionType` enums', }, diff --git a/packages/eslint-plugin-tslint/src/rules/config.ts b/packages/eslint-plugin-tslint/src/rules/config.ts index 77844d87932..15bd341aa28 100644 --- a/packages/eslint-plugin-tslint/src/rules/config.ts +++ b/packages/eslint-plugin-tslint/src/rules/config.ts @@ -65,7 +65,6 @@ export default createRule({ docs: { description: 'Wraps a TSLint configuration and lints the whole source using TSLint', // eslint-disable-line eslint-plugin/require-meta-docs-description - recommended: false, }, fixable: 'code', type: 'problem', diff --git a/packages/eslint-plugin/src/configs/all.ts b/packages/eslint-plugin/src/configs/all.ts index 67e0105759e..de250db29af 100644 --- a/packages/eslint-plugin/src/configs/all.ts +++ b/packages/eslint-plugin/src/configs/all.ts @@ -1,6 +1,9 @@ // THIS CODE WAS AUTOMATICALLY GENERATED // DO NOT EDIT THIS CODE BY HAND -// YOU CAN REGENERATE IT USING yarn generate:configs +// SEE https://typescript-eslint.io/linting/configs +// +// For developers working in the typescript-eslint monorepo: +// You can regenerate it using `yarn generate:configs` export = { extends: ['./configs/base', './configs/eslint-recommended'], diff --git a/packages/eslint-plugin/src/configs/base.ts b/packages/eslint-plugin/src/configs/base.ts index 528e00c7778..628ed42b760 100644 --- a/packages/eslint-plugin/src/configs/base.ts +++ b/packages/eslint-plugin/src/configs/base.ts @@ -1,6 +1,9 @@ // THIS CODE WAS AUTOMATICALLY GENERATED // DO NOT EDIT THIS CODE BY HAND -// YOU CAN REGENERATE IT USING yarn generate:configs +// SEE https://typescript-eslint.io/linting/configs +// +// For developers working in the typescript-eslint monorepo: +// You can regenerate it using `yarn generate:configs` export = { parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/src/configs/recommended-requiring-type-checking.ts b/packages/eslint-plugin/src/configs/recommended-requiring-type-checking.ts deleted file mode 100644 index 369d33d6687..00000000000 --- a/packages/eslint-plugin/src/configs/recommended-requiring-type-checking.ts +++ /dev/null @@ -1,26 +0,0 @@ -// THIS CODE WAS AUTOMATICALLY GENERATED -// DO NOT EDIT THIS CODE BY HAND -// YOU CAN REGENERATE IT USING yarn generate:configs - -export = { - extends: ['./configs/base', './configs/eslint-recommended'], - rules: { - '@typescript-eslint/await-thenable': 'error', - '@typescript-eslint/no-floating-promises': 'error', - '@typescript-eslint/no-for-in-array': 'error', - 'no-implied-eval': 'off', - '@typescript-eslint/no-implied-eval': 'error', - '@typescript-eslint/no-misused-promises': 'error', - '@typescript-eslint/no-unnecessary-type-assertion': 'error', - '@typescript-eslint/no-unsafe-argument': 'error', - '@typescript-eslint/no-unsafe-assignment': 'error', - '@typescript-eslint/no-unsafe-call': 'error', - '@typescript-eslint/no-unsafe-member-access': 'error', - '@typescript-eslint/no-unsafe-return': 'error', - 'require-await': 'off', - '@typescript-eslint/require-await': 'error', - '@typescript-eslint/restrict-plus-operands': 'error', - '@typescript-eslint/restrict-template-expressions': 'error', - '@typescript-eslint/unbound-method': 'error', - }, -}; diff --git a/packages/eslint-plugin/src/configs/recommended-type-checked.ts b/packages/eslint-plugin/src/configs/recommended-type-checked.ts new file mode 100644 index 00000000000..27c128ec3c0 --- /dev/null +++ b/packages/eslint-plugin/src/configs/recommended-type-checked.ts @@ -0,0 +1,47 @@ +// THIS CODE WAS AUTOMATICALLY GENERATED +// DO NOT EDIT THIS CODE BY HAND +// SEE https://typescript-eslint.io/linting/configs +// +// For developers working in the typescript-eslint monorepo: +// You can regenerate it using `yarn generate:configs` + +export = { + extends: ['./configs/base', './configs/eslint-recommended'], + rules: { + '@typescript-eslint/await-thenable': 'error', + '@typescript-eslint/ban-ts-comment': 'error', + '@typescript-eslint/ban-types': 'error', + 'no-array-constructor': 'off', + '@typescript-eslint/no-array-constructor': 'error', + '@typescript-eslint/no-duplicate-enum-values': 'error', + '@typescript-eslint/no-extra-non-null-assertion': 'error', + '@typescript-eslint/no-floating-promises': 'error', + '@typescript-eslint/no-for-in-array': 'error', + 'no-implied-eval': 'off', + '@typescript-eslint/no-implied-eval': 'error', + 'no-loss-of-precision': 'off', + '@typescript-eslint/no-loss-of-precision': 'error', + '@typescript-eslint/no-misused-new': 'error', + '@typescript-eslint/no-misused-promises': 'error', + '@typescript-eslint/no-namespace': 'error', + '@typescript-eslint/no-non-null-asserted-optional-chain': 'error', + '@typescript-eslint/no-this-alias': 'error', + '@typescript-eslint/no-unnecessary-type-assertion': 'error', + '@typescript-eslint/no-unnecessary-type-constraint': 'error', + '@typescript-eslint/no-unsafe-argument': 'error', + '@typescript-eslint/no-unsafe-assignment': 'error', + '@typescript-eslint/no-unsafe-call': 'error', + '@typescript-eslint/no-unsafe-member-access': 'error', + '@typescript-eslint/no-unsafe-return': 'error', + 'no-unused-vars': 'off', + '@typescript-eslint/no-unused-vars': 'error', + '@typescript-eslint/no-var-requires': 'error', + '@typescript-eslint/prefer-as-const': 'error', + 'require-await': 'off', + '@typescript-eslint/require-await': 'error', + '@typescript-eslint/restrict-plus-operands': 'error', + '@typescript-eslint/restrict-template-expressions': 'error', + '@typescript-eslint/triple-slash-reference': 'error', + '@typescript-eslint/unbound-method': 'error', + }, +}; diff --git a/packages/eslint-plugin/src/configs/recommended.ts b/packages/eslint-plugin/src/configs/recommended.ts index 10b1d04581f..3c2ec73e265 100644 --- a/packages/eslint-plugin/src/configs/recommended.ts +++ b/packages/eslint-plugin/src/configs/recommended.ts @@ -1,36 +1,30 @@ // THIS CODE WAS AUTOMATICALLY GENERATED // DO NOT EDIT THIS CODE BY HAND -// YOU CAN REGENERATE IT USING yarn generate:configs +// SEE https://typescript-eslint.io/linting/configs +// +// For developers working in the typescript-eslint monorepo: +// You can regenerate it using `yarn generate:configs` export = { extends: ['./configs/base', './configs/eslint-recommended'], rules: { - '@typescript-eslint/adjacent-overload-signatures': 'error', '@typescript-eslint/ban-ts-comment': 'error', '@typescript-eslint/ban-types': 'error', 'no-array-constructor': 'off', '@typescript-eslint/no-array-constructor': 'error', - 'no-empty-function': 'off', - '@typescript-eslint/no-empty-function': 'error', - '@typescript-eslint/no-empty-interface': 'error', - '@typescript-eslint/no-explicit-any': 'warn', + '@typescript-eslint/no-duplicate-enum-values': 'error', '@typescript-eslint/no-extra-non-null-assertion': 'error', - 'no-extra-semi': 'off', - '@typescript-eslint/no-extra-semi': 'error', - '@typescript-eslint/no-inferrable-types': 'error', 'no-loss-of-precision': 'off', '@typescript-eslint/no-loss-of-precision': 'error', '@typescript-eslint/no-misused-new': 'error', '@typescript-eslint/no-namespace': 'error', '@typescript-eslint/no-non-null-asserted-optional-chain': 'error', - '@typescript-eslint/no-non-null-assertion': 'warn', '@typescript-eslint/no-this-alias': 'error', '@typescript-eslint/no-unnecessary-type-constraint': 'error', 'no-unused-vars': 'off', - '@typescript-eslint/no-unused-vars': 'warn', + '@typescript-eslint/no-unused-vars': 'error', '@typescript-eslint/no-var-requires': 'error', '@typescript-eslint/prefer-as-const': 'error', - '@typescript-eslint/prefer-namespace-keyword': 'error', '@typescript-eslint/triple-slash-reference': 'error', }, }; diff --git a/packages/eslint-plugin/src/configs/strict-type-checked.ts b/packages/eslint-plugin/src/configs/strict-type-checked.ts new file mode 100644 index 00000000000..923f0ecf633 --- /dev/null +++ b/packages/eslint-plugin/src/configs/strict-type-checked.ts @@ -0,0 +1,69 @@ +// THIS CODE WAS AUTOMATICALLY GENERATED +// DO NOT EDIT THIS CODE BY HAND +// SEE https://typescript-eslint.io/linting/configs +// +// For developers working in the typescript-eslint monorepo: +// You can regenerate it using `yarn generate:configs` + +export = { + extends: ['./configs/base', './configs/eslint-recommended'], + rules: { + '@typescript-eslint/await-thenable': 'error', + '@typescript-eslint/ban-ts-comment': 'error', + '@typescript-eslint/ban-types': 'error', + 'no-array-constructor': 'off', + '@typescript-eslint/no-array-constructor': 'error', + '@typescript-eslint/no-base-to-string': 'error', + '@typescript-eslint/no-duplicate-enum-values': 'error', + '@typescript-eslint/no-dynamic-delete': 'error', + '@typescript-eslint/no-explicit-any': 'error', + '@typescript-eslint/no-extra-non-null-assertion': 'error', + '@typescript-eslint/no-extraneous-class': 'error', + '@typescript-eslint/no-floating-promises': 'error', + '@typescript-eslint/no-for-in-array': 'error', + 'no-implied-eval': 'off', + '@typescript-eslint/no-implied-eval': 'error', + '@typescript-eslint/no-invalid-void-type': 'error', + 'no-loss-of-precision': 'off', + '@typescript-eslint/no-loss-of-precision': 'error', + '@typescript-eslint/no-meaningless-void-operator': 'error', + '@typescript-eslint/no-misused-new': 'error', + '@typescript-eslint/no-misused-promises': 'error', + '@typescript-eslint/no-namespace': 'error', + '@typescript-eslint/no-non-null-asserted-nullish-coalescing': 'error', + '@typescript-eslint/no-non-null-asserted-optional-chain': 'error', + '@typescript-eslint/no-non-null-assertion': 'error', + '@typescript-eslint/no-this-alias': 'error', + 'no-throw-literal': 'off', + '@typescript-eslint/no-throw-literal': 'error', + '@typescript-eslint/no-unnecessary-boolean-literal-compare': 'error', + '@typescript-eslint/no-unnecessary-condition': 'error', + '@typescript-eslint/no-unnecessary-type-arguments': 'error', + '@typescript-eslint/no-unnecessary-type-assertion': 'error', + '@typescript-eslint/no-unnecessary-type-constraint': 'error', + '@typescript-eslint/no-unsafe-argument': 'error', + '@typescript-eslint/no-unsafe-assignment': 'error', + '@typescript-eslint/no-unsafe-call': 'error', + '@typescript-eslint/no-unsafe-declaration-merging': 'error', + '@typescript-eslint/no-unsafe-member-access': 'error', + '@typescript-eslint/no-unsafe-return': 'error', + 'no-unused-vars': 'off', + '@typescript-eslint/no-unused-vars': 'error', + 'no-useless-constructor': 'off', + '@typescript-eslint/no-useless-constructor': 'error', + '@typescript-eslint/no-var-requires': 'error', + '@typescript-eslint/prefer-as-const': 'error', + '@typescript-eslint/prefer-includes': 'error', + '@typescript-eslint/prefer-literal-enum-member': 'error', + '@typescript-eslint/prefer-reduce-type-parameter': 'error', + '@typescript-eslint/prefer-return-this-type': 'error', + '@typescript-eslint/prefer-ts-expect-error': 'error', + 'require-await': 'off', + '@typescript-eslint/require-await': 'error', + '@typescript-eslint/restrict-plus-operands': 'error', + '@typescript-eslint/restrict-template-expressions': 'error', + '@typescript-eslint/triple-slash-reference': 'error', + '@typescript-eslint/unbound-method': 'error', + '@typescript-eslint/unified-signatures': 'error', + }, +}; diff --git a/packages/eslint-plugin/src/configs/strict.ts b/packages/eslint-plugin/src/configs/strict.ts index 99b4e83b508..98553e52bf7 100644 --- a/packages/eslint-plugin/src/configs/strict.ts +++ b/packages/eslint-plugin/src/configs/strict.ts @@ -1,46 +1,42 @@ // THIS CODE WAS AUTOMATICALLY GENERATED // DO NOT EDIT THIS CODE BY HAND -// YOU CAN REGENERATE IT USING yarn generate:configs +// SEE https://typescript-eslint.io/linting/configs +// +// For developers working in the typescript-eslint monorepo: +// You can regenerate it using `yarn generate:configs` export = { extends: ['./configs/base', './configs/eslint-recommended'], rules: { - '@typescript-eslint/array-type': 'warn', - '@typescript-eslint/ban-tslint-comment': 'warn', - '@typescript-eslint/class-literal-property-style': 'warn', - '@typescript-eslint/consistent-generic-constructors': 'warn', - '@typescript-eslint/consistent-indexed-object-style': 'warn', - '@typescript-eslint/consistent-type-assertions': 'warn', - '@typescript-eslint/consistent-type-definitions': 'warn', - 'dot-notation': 'off', - '@typescript-eslint/dot-notation': 'warn', - '@typescript-eslint/no-base-to-string': 'warn', - '@typescript-eslint/no-confusing-non-null-assertion': 'warn', - '@typescript-eslint/no-duplicate-enum-values': 'warn', - '@typescript-eslint/no-dynamic-delete': 'warn', - '@typescript-eslint/no-extraneous-class': 'warn', - '@typescript-eslint/no-invalid-void-type': 'warn', - '@typescript-eslint/no-meaningless-void-operator': 'warn', - '@typescript-eslint/no-non-null-asserted-nullish-coalescing': 'warn', - 'no-throw-literal': 'off', - '@typescript-eslint/no-throw-literal': 'warn', - '@typescript-eslint/no-unnecessary-boolean-literal-compare': 'warn', - '@typescript-eslint/no-unnecessary-condition': 'warn', - '@typescript-eslint/no-unnecessary-type-arguments': 'warn', - '@typescript-eslint/no-unsafe-declaration-merging': 'warn', + '@typescript-eslint/ban-ts-comment': 'error', + '@typescript-eslint/ban-types': 'error', + 'no-array-constructor': 'off', + '@typescript-eslint/no-array-constructor': 'error', + '@typescript-eslint/no-duplicate-enum-values': 'error', + '@typescript-eslint/no-dynamic-delete': 'error', + '@typescript-eslint/no-explicit-any': 'error', + '@typescript-eslint/no-extra-non-null-assertion': 'error', + '@typescript-eslint/no-extraneous-class': 'error', + '@typescript-eslint/no-invalid-void-type': 'error', + 'no-loss-of-precision': 'off', + '@typescript-eslint/no-loss-of-precision': 'error', + '@typescript-eslint/no-misused-new': 'error', + '@typescript-eslint/no-namespace': 'error', + '@typescript-eslint/no-non-null-asserted-nullish-coalescing': 'error', + '@typescript-eslint/no-non-null-asserted-optional-chain': 'error', + '@typescript-eslint/no-non-null-assertion': 'error', + '@typescript-eslint/no-this-alias': 'error', + '@typescript-eslint/no-unnecessary-type-constraint': 'error', + '@typescript-eslint/no-unsafe-declaration-merging': 'error', + 'no-unused-vars': 'off', + '@typescript-eslint/no-unused-vars': 'error', 'no-useless-constructor': 'off', - '@typescript-eslint/no-useless-constructor': 'warn', - '@typescript-eslint/non-nullable-type-assertion-style': 'warn', - '@typescript-eslint/prefer-for-of': 'warn', - '@typescript-eslint/prefer-function-type': 'warn', - '@typescript-eslint/prefer-includes': 'warn', - '@typescript-eslint/prefer-literal-enum-member': 'warn', - '@typescript-eslint/prefer-nullish-coalescing': 'warn', - '@typescript-eslint/prefer-optional-chain': 'warn', - '@typescript-eslint/prefer-reduce-type-parameter': 'warn', - '@typescript-eslint/prefer-return-this-type': 'warn', - '@typescript-eslint/prefer-string-starts-ends-with': 'warn', - '@typescript-eslint/prefer-ts-expect-error': 'warn', - '@typescript-eslint/unified-signatures': 'warn', + '@typescript-eslint/no-useless-constructor': 'error', + '@typescript-eslint/no-var-requires': 'error', + '@typescript-eslint/prefer-as-const': 'error', + '@typescript-eslint/prefer-literal-enum-member': 'error', + '@typescript-eslint/prefer-ts-expect-error': 'error', + '@typescript-eslint/triple-slash-reference': 'error', + '@typescript-eslint/unified-signatures': 'error', }, }; diff --git a/packages/eslint-plugin/src/configs/stylistic-type-checked.ts b/packages/eslint-plugin/src/configs/stylistic-type-checked.ts new file mode 100644 index 00000000000..9ce234d4676 --- /dev/null +++ b/packages/eslint-plugin/src/configs/stylistic-type-checked.ts @@ -0,0 +1,35 @@ +// THIS CODE WAS AUTOMATICALLY GENERATED +// DO NOT EDIT THIS CODE BY HAND +// SEE https://typescript-eslint.io/linting/configs +// +// For developers working in the typescript-eslint monorepo: +// You can regenerate it using `yarn generate:configs` + +export = { + extends: ['./configs/base', './configs/eslint-recommended'], + rules: { + '@typescript-eslint/adjacent-overload-signatures': 'error', + '@typescript-eslint/array-type': 'error', + '@typescript-eslint/ban-tslint-comment': 'error', + '@typescript-eslint/class-literal-property-style': 'error', + '@typescript-eslint/consistent-generic-constructors': 'error', + '@typescript-eslint/consistent-indexed-object-style': 'error', + '@typescript-eslint/consistent-type-assertions': 'error', + '@typescript-eslint/consistent-type-definitions': 'error', + 'dot-notation': 'off', + '@typescript-eslint/dot-notation': 'error', + '@typescript-eslint/no-confusing-non-null-assertion': 'error', + 'no-empty-function': 'off', + '@typescript-eslint/no-empty-function': 'error', + '@typescript-eslint/no-empty-interface': 'error', + '@typescript-eslint/no-inferrable-types': 'error', + '@typescript-eslint/non-nullable-type-assertion-style': 'error', + '@typescript-eslint/prefer-for-of': 'error', + '@typescript-eslint/prefer-function-type': 'error', + '@typescript-eslint/prefer-namespace-keyword': 'error', + '@typescript-eslint/prefer-nullish-coalescing': 'error', + '@typescript-eslint/prefer-optional-chain': 'error', + '@typescript-eslint/prefer-string-starts-ends-with': 'error', + '@typescript-eslint/sort-type-constituents': 'error', + }, +}; diff --git a/packages/eslint-plugin/src/configs/stylistic.ts b/packages/eslint-plugin/src/configs/stylistic.ts new file mode 100644 index 00000000000..ed5ce3ded8c --- /dev/null +++ b/packages/eslint-plugin/src/configs/stylistic.ts @@ -0,0 +1,30 @@ +// THIS CODE WAS AUTOMATICALLY GENERATED +// DO NOT EDIT THIS CODE BY HAND +// SEE https://typescript-eslint.io/linting/configs +// +// For developers working in the typescript-eslint monorepo: +// You can regenerate it using `yarn generate:configs` + +export = { + extends: ['./configs/base', './configs/eslint-recommended'], + rules: { + '@typescript-eslint/adjacent-overload-signatures': 'error', + '@typescript-eslint/array-type': 'error', + '@typescript-eslint/ban-tslint-comment': 'error', + '@typescript-eslint/class-literal-property-style': 'error', + '@typescript-eslint/consistent-generic-constructors': 'error', + '@typescript-eslint/consistent-indexed-object-style': 'error', + '@typescript-eslint/consistent-type-assertions': 'error', + '@typescript-eslint/consistent-type-definitions': 'error', + '@typescript-eslint/no-confusing-non-null-assertion': 'error', + 'no-empty-function': 'off', + '@typescript-eslint/no-empty-function': 'error', + '@typescript-eslint/no-empty-interface': 'error', + '@typescript-eslint/no-inferrable-types': 'error', + '@typescript-eslint/prefer-for-of': 'error', + '@typescript-eslint/prefer-function-type': 'error', + '@typescript-eslint/prefer-namespace-keyword': 'error', + '@typescript-eslint/prefer-optional-chain': 'error', + '@typescript-eslint/sort-type-constituents': 'error', + }, +}; diff --git a/packages/eslint-plugin/src/index.ts b/packages/eslint-plugin/src/index.ts index 03899ac43cb..95fafdecdc3 100644 --- a/packages/eslint-plugin/src/index.ts +++ b/packages/eslint-plugin/src/index.ts @@ -2,18 +2,25 @@ import all from './configs/all'; import base from './configs/base'; import eslintRecommended from './configs/eslint-recommended'; import recommended from './configs/recommended'; -import recommendedRequiringTypeChecking from './configs/recommended-requiring-type-checking'; +import recommendedTypeChecked from './configs/recommended-type-checked'; import strict from './configs/strict'; +import strictTypeChecked from './configs/strict-type-checked'; +import stylistic from './configs/stylistic'; +import stylisticTypeChecked from './configs/stylistic-type-checked'; import rules from './rules'; export = { - rules, configs: { all, base, - recommended, 'eslint-recommended': eslintRecommended, - 'recommended-requiring-type-checking': recommendedRequiringTypeChecking, + recommended, + 'recommended-requiring-type-checking': recommendedTypeChecked, + 'recommended-type-checked': recommendedTypeChecked, strict, + 'strict-type-checked': strictTypeChecked, + stylistic, + 'stylistic-type-checked': stylisticTypeChecked, }, + rules, }; diff --git a/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts b/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts index 498a9bf5ae1..3b52ffb0b68 100644 --- a/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts +++ b/packages/eslint-plugin/src/rules/adjacent-overload-signatures.ts @@ -21,7 +21,7 @@ export default util.createRule({ type: 'suggestion', docs: { description: 'Require that function overload signatures be consecutive', - recommended: 'error', + recommended: 'stylistic', }, schema: [], messages: { diff --git a/packages/eslint-plugin/src/rules/array-type.ts b/packages/eslint-plugin/src/rules/array-type.ts index b29fbc8f4dc..d2fabdcc6ad 100644 --- a/packages/eslint-plugin/src/rules/array-type.ts +++ b/packages/eslint-plugin/src/rules/array-type.ts @@ -92,7 +92,7 @@ export default util.createRule({ docs: { description: 'Require consistently using either `T[]` or `Array` for arrays', - recommended: 'strict', + recommended: 'stylistic', }, fixable: 'code', messages: { diff --git a/packages/eslint-plugin/src/rules/await-thenable.ts b/packages/eslint-plugin/src/rules/await-thenable.ts index 940ddb75662..86d1688da02 100644 --- a/packages/eslint-plugin/src/rules/await-thenable.ts +++ b/packages/eslint-plugin/src/rules/await-thenable.ts @@ -7,7 +7,7 @@ export default util.createRule({ meta: { docs: { description: 'Disallow awaiting a value that is not a Thenable', - recommended: 'error', + recommended: 'recommended', requiresTypeChecking: true, }, messages: { diff --git a/packages/eslint-plugin/src/rules/ban-ts-comment.ts b/packages/eslint-plugin/src/rules/ban-ts-comment.ts index 511a951280e..818c23968eb 100644 --- a/packages/eslint-plugin/src/rules/ban-ts-comment.ts +++ b/packages/eslint-plugin/src/rules/ban-ts-comment.ts @@ -29,7 +29,7 @@ export default util.createRule<[Options], MessageIds>({ docs: { description: 'Disallow `@ts-` comments or require descriptions after directives', - recommended: 'error', + recommended: 'recommended', }, messages: { tsDirectiveComment: diff --git a/packages/eslint-plugin/src/rules/ban-tslint-comment.ts b/packages/eslint-plugin/src/rules/ban-tslint-comment.ts index 849fbcc911e..8a920faddf5 100644 --- a/packages/eslint-plugin/src/rules/ban-tslint-comment.ts +++ b/packages/eslint-plugin/src/rules/ban-tslint-comment.ts @@ -21,7 +21,7 @@ export default util.createRule({ type: 'suggestion', docs: { description: 'Disallow `// tslint:` comments', - recommended: 'strict', + recommended: 'stylistic', }, messages: { commentDetected: 'tslint comment detected: "{{ text }}"', diff --git a/packages/eslint-plugin/src/rules/ban-types.ts b/packages/eslint-plugin/src/rules/ban-types.ts index f21dda8a249..c6806f2a79d 100644 --- a/packages/eslint-plugin/src/rules/ban-types.ts +++ b/packages/eslint-plugin/src/rules/ban-types.ts @@ -120,7 +120,7 @@ export default util.createRule({ type: 'suggestion', docs: { description: 'Disallow certain types', - recommended: 'error', + recommended: 'recommended', }, fixable: 'code', messages: { diff --git a/packages/eslint-plugin/src/rules/block-spacing.ts b/packages/eslint-plugin/src/rules/block-spacing.ts index 745132978f7..8141a979cf0 100644 --- a/packages/eslint-plugin/src/rules/block-spacing.ts +++ b/packages/eslint-plugin/src/rules/block-spacing.ts @@ -16,7 +16,6 @@ export default util.createRule({ docs: { description: 'Disallow or enforce spaces inside of blocks after opening block and before closing block', - recommended: false, extendsBaseRule: true, }, fixable: 'whitespace', diff --git a/packages/eslint-plugin/src/rules/brace-style.ts b/packages/eslint-plugin/src/rules/brace-style.ts index 43d4ba63c3c..0b5b543e067 100644 --- a/packages/eslint-plugin/src/rules/brace-style.ts +++ b/packages/eslint-plugin/src/rules/brace-style.ts @@ -18,7 +18,6 @@ export default createRule({ type: 'layout', docs: { description: 'Enforce consistent brace style for blocks', - recommended: false, extendsBaseRule: true, }, messages: baseRule.meta.messages, diff --git a/packages/eslint-plugin/src/rules/class-literal-property-style.ts b/packages/eslint-plugin/src/rules/class-literal-property-style.ts index ed49b144e47..7e4d6b2d6b1 100644 --- a/packages/eslint-plugin/src/rules/class-literal-property-style.ts +++ b/packages/eslint-plugin/src/rules/class-literal-property-style.ts @@ -43,7 +43,7 @@ export default util.createRule({ docs: { description: 'Enforce that literals on classes are exposed in a consistent style', - recommended: 'strict', + recommended: 'stylistic', }, fixable: 'code', messages: { diff --git a/packages/eslint-plugin/src/rules/comma-dangle.ts b/packages/eslint-plugin/src/rules/comma-dangle.ts index 149218c4e7e..119907db762 100644 --- a/packages/eslint-plugin/src/rules/comma-dangle.ts +++ b/packages/eslint-plugin/src/rules/comma-dangle.ts @@ -44,7 +44,6 @@ export default util.createRule({ type: 'layout', docs: { description: 'Require or disallow trailing commas', - recommended: false, extendsBaseRule: true, }, schema: { diff --git a/packages/eslint-plugin/src/rules/comma-spacing.ts b/packages/eslint-plugin/src/rules/comma-spacing.ts index a1ebcc181f2..36f3751bef7 100644 --- a/packages/eslint-plugin/src/rules/comma-spacing.ts +++ b/packages/eslint-plugin/src/rules/comma-spacing.ts @@ -22,7 +22,6 @@ export default createRule({ type: 'layout', docs: { description: 'Enforce consistent spacing before and after commas', - recommended: false, extendsBaseRule: true, }, fixable: 'whitespace', diff --git a/packages/eslint-plugin/src/rules/consistent-generic-constructors.ts b/packages/eslint-plugin/src/rules/consistent-generic-constructors.ts index a024a50e600..5d3c9fce7d9 100644 --- a/packages/eslint-plugin/src/rules/consistent-generic-constructors.ts +++ b/packages/eslint-plugin/src/rules/consistent-generic-constructors.ts @@ -13,7 +13,7 @@ export default createRule({ docs: { description: 'Enforce specifying generic type arguments on type annotation or constructor name of a constructor call', - recommended: 'strict', + recommended: 'stylistic', }, messages: { preferTypeAnnotation: diff --git a/packages/eslint-plugin/src/rules/consistent-indexed-object-style.ts b/packages/eslint-plugin/src/rules/consistent-indexed-object-style.ts index 535692f3fa8..4a1b475a16f 100644 --- a/packages/eslint-plugin/src/rules/consistent-indexed-object-style.ts +++ b/packages/eslint-plugin/src/rules/consistent-indexed-object-style.ts @@ -12,7 +12,7 @@ export default createRule({ type: 'suggestion', docs: { description: 'Require or disallow the `Record` type', - recommended: 'strict', + recommended: 'stylistic', }, messages: { preferRecord: 'A record is preferred over an index signature.', diff --git a/packages/eslint-plugin/src/rules/consistent-type-assertions.ts b/packages/eslint-plugin/src/rules/consistent-type-assertions.ts index 41f255dea83..183880d2412 100644 --- a/packages/eslint-plugin/src/rules/consistent-type-assertions.ts +++ b/packages/eslint-plugin/src/rules/consistent-type-assertions.ts @@ -25,7 +25,7 @@ export default util.createRule({ type: 'suggestion', docs: { description: 'Enforce consistent usage of type assertions', - recommended: 'strict', + recommended: 'stylistic', }, messages: { as: "Use 'as {{cast}}' instead of '<{{cast}}>'.", diff --git a/packages/eslint-plugin/src/rules/consistent-type-definitions.ts b/packages/eslint-plugin/src/rules/consistent-type-definitions.ts index fdf7ac947c6..a28f07529b5 100644 --- a/packages/eslint-plugin/src/rules/consistent-type-definitions.ts +++ b/packages/eslint-plugin/src/rules/consistent-type-definitions.ts @@ -10,7 +10,7 @@ export default util.createRule({ docs: { description: 'Enforce type definitions to consistently use either `interface` or `type`', - recommended: 'strict', + recommended: 'stylistic', }, messages: { interfaceOverType: 'Use an `interface` instead of a `type`.', diff --git a/packages/eslint-plugin/src/rules/consistent-type-exports.ts b/packages/eslint-plugin/src/rules/consistent-type-exports.ts index 576b59eac5d..97b7d9c0504 100644 --- a/packages/eslint-plugin/src/rules/consistent-type-exports.ts +++ b/packages/eslint-plugin/src/rules/consistent-type-exports.ts @@ -35,7 +35,6 @@ export default util.createRule({ type: 'suggestion', docs: { description: 'Enforce consistent usage of type exports', - recommended: false, requiresTypeChecking: true, }, messages: { diff --git a/packages/eslint-plugin/src/rules/consistent-type-imports.ts b/packages/eslint-plugin/src/rules/consistent-type-imports.ts index 4c5cf771901..3b9de8bad83 100644 --- a/packages/eslint-plugin/src/rules/consistent-type-imports.ts +++ b/packages/eslint-plugin/src/rules/consistent-type-imports.ts @@ -46,7 +46,6 @@ export default util.createRule({ type: 'suggestion', docs: { description: 'Enforce consistent usage of type imports', - recommended: false, }, messages: { typeOverValue: diff --git a/packages/eslint-plugin/src/rules/default-param-last.ts b/packages/eslint-plugin/src/rules/default-param-last.ts index ba9d5da7b4e..e76ce14fa05 100644 --- a/packages/eslint-plugin/src/rules/default-param-last.ts +++ b/packages/eslint-plugin/src/rules/default-param-last.ts @@ -9,7 +9,6 @@ export default createRule({ type: 'suggestion', docs: { description: 'Enforce default parameters to be last', - recommended: false, extendsBaseRule: true, }, schema: [], diff --git a/packages/eslint-plugin/src/rules/dot-notation.ts b/packages/eslint-plugin/src/rules/dot-notation.ts index 400598b4f97..e6c0d9e7a83 100644 --- a/packages/eslint-plugin/src/rules/dot-notation.ts +++ b/packages/eslint-plugin/src/rules/dot-notation.ts @@ -20,7 +20,7 @@ export default createRule({ type: 'suggestion', docs: { description: 'Enforce dot notation whenever possible', - recommended: 'strict', + recommended: 'stylistic', extendsBaseRule: true, requiresTypeChecking: true, }, diff --git a/packages/eslint-plugin/src/rules/explicit-function-return-type.ts b/packages/eslint-plugin/src/rules/explicit-function-return-type.ts index 97905879dd7..dee2fe504f3 100644 --- a/packages/eslint-plugin/src/rules/explicit-function-return-type.ts +++ b/packages/eslint-plugin/src/rules/explicit-function-return-type.ts @@ -29,7 +29,6 @@ export default util.createRule({ docs: { description: 'Require explicit return types on functions and class methods', - recommended: false, }, messages: { missingReturnType: 'Missing return type on function.', diff --git a/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts b/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts index 3fc42a956f6..b095b903162 100644 --- a/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts +++ b/packages/eslint-plugin/src/rules/explicit-member-accessibility.ts @@ -53,7 +53,6 @@ export default util.createRule({ description: 'Require explicit accessibility modifiers on class properties and methods', // too opinionated to be recommended - recommended: false, }, fixable: 'code', messages: { diff --git a/packages/eslint-plugin/src/rules/explicit-module-boundary-types.ts b/packages/eslint-plugin/src/rules/explicit-module-boundary-types.ts index 669d85968a5..0e6c56038c5 100644 --- a/packages/eslint-plugin/src/rules/explicit-module-boundary-types.ts +++ b/packages/eslint-plugin/src/rules/explicit-module-boundary-types.ts @@ -38,7 +38,6 @@ export default util.createRule({ docs: { description: "Require explicit return and argument types on exported functions' and classes' public class methods", - recommended: false, }, messages: { missingReturnType: 'Missing return type on function.', diff --git a/packages/eslint-plugin/src/rules/func-call-spacing.ts b/packages/eslint-plugin/src/rules/func-call-spacing.ts index 31d8fa41046..0c737250526 100644 --- a/packages/eslint-plugin/src/rules/func-call-spacing.ts +++ b/packages/eslint-plugin/src/rules/func-call-spacing.ts @@ -20,7 +20,6 @@ export default util.createRule({ docs: { description: 'Require or disallow spacing between function identifiers and their invocations', - recommended: false, extendsBaseRule: true, }, fixable: 'whitespace', diff --git a/packages/eslint-plugin/src/rules/indent.ts b/packages/eslint-plugin/src/rules/indent.ts index 4973a790212..afb60fa0a23 100644 --- a/packages/eslint-plugin/src/rules/indent.ts +++ b/packages/eslint-plugin/src/rules/indent.ts @@ -91,7 +91,6 @@ export default util.createRule({ docs: { description: 'Enforce consistent indentation', // too opinionated to be recommended - recommended: false, extendsBaseRule: true, }, fixable: 'whitespace', diff --git a/packages/eslint-plugin/src/rules/init-declarations.ts b/packages/eslint-plugin/src/rules/init-declarations.ts index 04f7a1a262e..fabbe73898a 100644 --- a/packages/eslint-plugin/src/rules/init-declarations.ts +++ b/packages/eslint-plugin/src/rules/init-declarations.ts @@ -20,7 +20,6 @@ export default createRule({ docs: { description: 'Require or disallow initialization in variable declarations', - recommended: false, extendsBaseRule: true, }, hasSuggestions: baseRule.meta.hasSuggestions, diff --git a/packages/eslint-plugin/src/rules/key-spacing.ts b/packages/eslint-plugin/src/rules/key-spacing.ts index 2d4d3f5c11d..0fd0032c7c0 100644 --- a/packages/eslint-plugin/src/rules/key-spacing.ts +++ b/packages/eslint-plugin/src/rules/key-spacing.ts @@ -31,7 +31,6 @@ export default util.createRule({ docs: { description: 'Enforce consistent spacing between property names and type annotations in types and interfaces', - recommended: false, extendsBaseRule: true, }, fixable: 'whitespace', diff --git a/packages/eslint-plugin/src/rules/keyword-spacing.ts b/packages/eslint-plugin/src/rules/keyword-spacing.ts index aa09fb3d1b8..0ec1d17ec38 100644 --- a/packages/eslint-plugin/src/rules/keyword-spacing.ts +++ b/packages/eslint-plugin/src/rules/keyword-spacing.ts @@ -34,7 +34,6 @@ export default util.createRule({ type: 'layout', docs: { description: 'Enforce consistent spacing before and after keywords', - recommended: false, extendsBaseRule: true, }, fixable: 'whitespace', diff --git a/packages/eslint-plugin/src/rules/lines-between-class-members.ts b/packages/eslint-plugin/src/rules/lines-between-class-members.ts index 2f37b365dae..6a8cd735862 100644 --- a/packages/eslint-plugin/src/rules/lines-between-class-members.ts +++ b/packages/eslint-plugin/src/rules/lines-between-class-members.ts @@ -27,7 +27,6 @@ export default util.createRule({ type: 'layout', docs: { description: 'Require or disallow an empty line between class members', - recommended: false, extendsBaseRule: true, }, fixable: 'whitespace', diff --git a/packages/eslint-plugin/src/rules/member-delimiter-style.ts b/packages/eslint-plugin/src/rules/member-delimiter-style.ts index 53d2019e97d..62fe1cd9079 100644 --- a/packages/eslint-plugin/src/rules/member-delimiter-style.ts +++ b/packages/eslint-plugin/src/rules/member-delimiter-style.ts @@ -139,7 +139,6 @@ export default util.createRule({ docs: { description: 'Require a specific member delimiter style for interfaces and type literals', - recommended: false, }, fixable: 'whitespace', messages: { diff --git a/packages/eslint-plugin/src/rules/member-ordering.ts b/packages/eslint-plugin/src/rules/member-ordering.ts index f8db5ade0ca..a50cf6ba18d 100644 --- a/packages/eslint-plugin/src/rules/member-ordering.ts +++ b/packages/eslint-plugin/src/rules/member-ordering.ts @@ -584,7 +584,6 @@ export default util.createRule({ type: 'suggestion', docs: { description: 'Require a consistent member declaration order', - recommended: false, }, messages: { incorrectOrder: diff --git a/packages/eslint-plugin/src/rules/method-signature-style.ts b/packages/eslint-plugin/src/rules/method-signature-style.ts index 93b21408511..3cc8773159c 100644 --- a/packages/eslint-plugin/src/rules/method-signature-style.ts +++ b/packages/eslint-plugin/src/rules/method-signature-style.ts @@ -12,7 +12,6 @@ export default util.createRule({ type: 'suggestion', docs: { description: 'Enforce using a particular method signature syntax', - recommended: false, }, fixable: 'code', messages: { diff --git a/packages/eslint-plugin/src/rules/naming-convention-utils/parse-options.ts b/packages/eslint-plugin/src/rules/naming-convention-utils/parse-options.ts index c4e6e36b303..945777dd7fb 100644 --- a/packages/eslint-plugin/src/rules/naming-convention-utils/parse-options.ts +++ b/packages/eslint-plugin/src/rules/naming-convention-utils/parse-options.ts @@ -83,10 +83,13 @@ function parseOptions(context: Context): ParsedOptions { const normalizedOptions = context.options .map(opt => normalizeOption(opt)) .reduce((acc, val) => acc.concat(val), []); - return util.getEnumNames(Selectors).reduce((acc, k) => { + + const result = util.getEnumNames(Selectors).reduce((acc, k) => { acc[k] = createValidator(k, context, normalizedOptions); return acc; }, {} as ParsedOptions); + + return result; } export { parseOptions }; diff --git a/packages/eslint-plugin/src/rules/naming-convention.ts b/packages/eslint-plugin/src/rules/naming-convention.ts index 84f1c1cfdcb..b4f769cb836 100644 --- a/packages/eslint-plugin/src/rules/naming-convention.ts +++ b/packages/eslint-plugin/src/rules/naming-convention.ts @@ -53,7 +53,6 @@ export default util.createRule({ docs: { description: 'Enforce naming conventions for everything across a codebase', - recommended: false, // technically only requires type checking if the user uses "type" modifiers requiresTypeChecking: true, }, diff --git a/packages/eslint-plugin/src/rules/no-array-constructor.ts b/packages/eslint-plugin/src/rules/no-array-constructor.ts index 2b6105890ea..7ebff9b160d 100644 --- a/packages/eslint-plugin/src/rules/no-array-constructor.ts +++ b/packages/eslint-plugin/src/rules/no-array-constructor.ts @@ -9,7 +9,7 @@ export default util.createRule({ type: 'suggestion', docs: { description: 'Disallow generic `Array` constructors', - recommended: 'error', + recommended: 'recommended', extendsBaseRule: true, }, fixable: 'code', diff --git a/packages/eslint-plugin/src/rules/no-confusing-non-null-assertion.ts b/packages/eslint-plugin/src/rules/no-confusing-non-null-assertion.ts index 6268a9e6c75..f75396a27fe 100644 --- a/packages/eslint-plugin/src/rules/no-confusing-non-null-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-confusing-non-null-assertion.ts @@ -10,7 +10,7 @@ export default util.createRule({ docs: { description: 'Disallow non-null assertion in locations that may be confusing', - recommended: 'strict', + recommended: 'stylistic', }, fixable: 'code', hasSuggestions: true, diff --git a/packages/eslint-plugin/src/rules/no-confusing-void-expression.ts b/packages/eslint-plugin/src/rules/no-confusing-void-expression.ts index 0567ea810b9..2a8d6f5f604 100644 --- a/packages/eslint-plugin/src/rules/no-confusing-void-expression.ts +++ b/packages/eslint-plugin/src/rules/no-confusing-void-expression.ts @@ -28,7 +28,6 @@ export default util.createRule({ docs: { description: 'Require expressions of type void to appear in statement position', - recommended: false, requiresTypeChecking: true, }, messages: { diff --git a/packages/eslint-plugin/src/rules/no-dupe-class-members.ts b/packages/eslint-plugin/src/rules/no-dupe-class-members.ts index 62c1a8feb80..95689cae513 100644 --- a/packages/eslint-plugin/src/rules/no-dupe-class-members.ts +++ b/packages/eslint-plugin/src/rules/no-dupe-class-members.ts @@ -15,7 +15,6 @@ export default util.createRule({ type: 'problem', docs: { description: 'Disallow duplicate class members', - recommended: false, extendsBaseRule: true, }, hasSuggestions: baseRule.meta.hasSuggestions, diff --git a/packages/eslint-plugin/src/rules/no-duplicate-enum-values.ts b/packages/eslint-plugin/src/rules/no-duplicate-enum-values.ts index 4bb011d1234..323acb805a0 100644 --- a/packages/eslint-plugin/src/rules/no-duplicate-enum-values.ts +++ b/packages/eslint-plugin/src/rules/no-duplicate-enum-values.ts @@ -9,7 +9,7 @@ export default util.createRule({ type: 'problem', docs: { description: 'Disallow duplicate enum member values', - recommended: 'strict', + recommended: 'recommended', }, hasSuggestions: false, messages: { diff --git a/packages/eslint-plugin/src/rules/no-empty-function.ts b/packages/eslint-plugin/src/rules/no-empty-function.ts index a78e4b86db4..27131e99e83 100644 --- a/packages/eslint-plugin/src/rules/no-empty-function.ts +++ b/packages/eslint-plugin/src/rules/no-empty-function.ts @@ -46,7 +46,7 @@ export default util.createRule({ type: 'suggestion', docs: { description: 'Disallow empty functions', - recommended: 'error', + recommended: 'stylistic', extendsBaseRule: true, }, hasSuggestions: baseRule.meta.hasSuggestions, diff --git a/packages/eslint-plugin/src/rules/no-empty-interface.ts b/packages/eslint-plugin/src/rules/no-empty-interface.ts index d74034114bb..d44a92eb908 100644 --- a/packages/eslint-plugin/src/rules/no-empty-interface.ts +++ b/packages/eslint-plugin/src/rules/no-empty-interface.ts @@ -16,7 +16,7 @@ export default util.createRule({ type: 'suggestion', docs: { description: 'Disallow the declaration of empty interfaces', - recommended: 'error', + recommended: 'stylistic', }, fixable: 'code', hasSuggestions: true, diff --git a/packages/eslint-plugin/src/rules/no-explicit-any.ts b/packages/eslint-plugin/src/rules/no-explicit-any.ts index 707f2148162..b8a4f5e553a 100644 --- a/packages/eslint-plugin/src/rules/no-explicit-any.ts +++ b/packages/eslint-plugin/src/rules/no-explicit-any.ts @@ -17,7 +17,7 @@ export default util.createRule({ type: 'suggestion', docs: { description: 'Disallow the `any` type', - recommended: 'warn', + recommended: 'strict', }, fixable: 'code', hasSuggestions: true, diff --git a/packages/eslint-plugin/src/rules/no-extra-non-null-assertion.ts b/packages/eslint-plugin/src/rules/no-extra-non-null-assertion.ts index a69cd262d6e..082c3d212a6 100644 --- a/packages/eslint-plugin/src/rules/no-extra-non-null-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-extra-non-null-assertion.ts @@ -8,7 +8,7 @@ export default util.createRule({ type: 'problem', docs: { description: 'Disallow extra non-null assertions', - recommended: 'error', + recommended: 'recommended', }, fixable: 'code', schema: [], diff --git a/packages/eslint-plugin/src/rules/no-extra-parens.ts b/packages/eslint-plugin/src/rules/no-extra-parens.ts index a44276a0a76..8cef29d4a62 100644 --- a/packages/eslint-plugin/src/rules/no-extra-parens.ts +++ b/packages/eslint-plugin/src/rules/no-extra-parens.ts @@ -18,7 +18,6 @@ export default util.createRule({ type: 'layout', docs: { description: 'Disallow unnecessary parentheses', - recommended: false, extendsBaseRule: true, }, fixable: 'code', diff --git a/packages/eslint-plugin/src/rules/no-extra-semi.ts b/packages/eslint-plugin/src/rules/no-extra-semi.ts index 6fcfb4871ee..d2860771c53 100644 --- a/packages/eslint-plugin/src/rules/no-extra-semi.ts +++ b/packages/eslint-plugin/src/rules/no-extra-semi.ts @@ -12,7 +12,6 @@ export default util.createRule({ type: 'suggestion', docs: { description: 'Disallow unnecessary semicolons', - recommended: 'error', extendsBaseRule: true, }, fixable: 'code', diff --git a/packages/eslint-plugin/src/rules/no-floating-promises.ts b/packages/eslint-plugin/src/rules/no-floating-promises.ts index 126b0a0188a..77ce7dfbc34 100644 --- a/packages/eslint-plugin/src/rules/no-floating-promises.ts +++ b/packages/eslint-plugin/src/rules/no-floating-promises.ts @@ -25,7 +25,7 @@ export default util.createRule({ docs: { description: 'Require Promise-like statements to be handled appropriately', - recommended: 'error', + recommended: 'recommended', requiresTypeChecking: true, }, hasSuggestions: true, diff --git a/packages/eslint-plugin/src/rules/no-for-in-array.ts b/packages/eslint-plugin/src/rules/no-for-in-array.ts index 927939b8598..ab6e9832165 100644 --- a/packages/eslint-plugin/src/rules/no-for-in-array.ts +++ b/packages/eslint-plugin/src/rules/no-for-in-array.ts @@ -7,7 +7,7 @@ export default util.createRule({ meta: { docs: { description: 'Disallow iterating over an array with a for-in loop', - recommended: 'error', + recommended: 'recommended', requiresTypeChecking: true, }, messages: { diff --git a/packages/eslint-plugin/src/rules/no-implied-eval.ts b/packages/eslint-plugin/src/rules/no-implied-eval.ts index b0a97efb69c..0e042232f61 100644 --- a/packages/eslint-plugin/src/rules/no-implied-eval.ts +++ b/packages/eslint-plugin/src/rules/no-implied-eval.ts @@ -19,7 +19,7 @@ export default util.createRule({ meta: { docs: { description: 'Disallow the use of `eval()`-like methods', - recommended: 'error', + recommended: 'recommended', extendsBaseRule: true, requiresTypeChecking: true, }, diff --git a/packages/eslint-plugin/src/rules/no-import-type-side-effects.ts b/packages/eslint-plugin/src/rules/no-import-type-side-effects.ts index 941aa93e72a..0e814a0ca48 100644 --- a/packages/eslint-plugin/src/rules/no-import-type-side-effects.ts +++ b/packages/eslint-plugin/src/rules/no-import-type-side-effects.ts @@ -13,7 +13,6 @@ export default util.createRule({ docs: { description: 'Enforce the use of top-level import type qualifier when an import only has specifiers with inline type qualifiers', - recommended: false, }, fixable: 'code', messages: { diff --git a/packages/eslint-plugin/src/rules/no-inferrable-types.ts b/packages/eslint-plugin/src/rules/no-inferrable-types.ts index 1bc83c07c70..4a1ed72eff8 100644 --- a/packages/eslint-plugin/src/rules/no-inferrable-types.ts +++ b/packages/eslint-plugin/src/rules/no-inferrable-types.ts @@ -19,7 +19,7 @@ export default util.createRule({ docs: { description: 'Disallow explicit type declarations for variables or parameters initialized to a number, string, or boolean', - recommended: 'error', + recommended: 'stylistic', }, fixable: 'code', messages: { diff --git a/packages/eslint-plugin/src/rules/no-invalid-this.ts b/packages/eslint-plugin/src/rules/no-invalid-this.ts index 5cf502a7af9..c1acdb24fe7 100644 --- a/packages/eslint-plugin/src/rules/no-invalid-this.ts +++ b/packages/eslint-plugin/src/rules/no-invalid-this.ts @@ -20,7 +20,6 @@ export default createRule({ docs: { description: 'Disallow `this` keywords outside of classes or class-like objects', - recommended: false, extendsBaseRule: true, }, messages: baseRule.meta.messages, diff --git a/packages/eslint-plugin/src/rules/no-loop-func.ts b/packages/eslint-plugin/src/rules/no-loop-func.ts index 9e24cef086c..5fcac7e417e 100644 --- a/packages/eslint-plugin/src/rules/no-loop-func.ts +++ b/packages/eslint-plugin/src/rules/no-loop-func.ts @@ -16,7 +16,6 @@ export default util.createRule({ docs: { description: 'Disallow function declarations that contain unsafe references inside loop statements', - recommended: false, extendsBaseRule: true, }, hasSuggestions: baseRule.meta.hasSuggestions, diff --git a/packages/eslint-plugin/src/rules/no-loss-of-precision.ts b/packages/eslint-plugin/src/rules/no-loss-of-precision.ts index 2c0d84364e4..8a07f975ab1 100644 --- a/packages/eslint-plugin/src/rules/no-loss-of-precision.ts +++ b/packages/eslint-plugin/src/rules/no-loss-of-precision.ts @@ -16,7 +16,7 @@ export default util.createRule({ type: 'problem', docs: { description: 'Disallow literal numbers that lose precision', - recommended: 'error', + recommended: 'recommended', extendsBaseRule: true, }, hasSuggestions: baseRule?.meta.hasSuggestions, diff --git a/packages/eslint-plugin/src/rules/no-magic-numbers.ts b/packages/eslint-plugin/src/rules/no-magic-numbers.ts index 604e82d2186..18ae31abea0 100644 --- a/packages/eslint-plugin/src/rules/no-magic-numbers.ts +++ b/packages/eslint-plugin/src/rules/no-magic-numbers.ts @@ -39,7 +39,6 @@ export default util.createRule({ type: 'suggestion', docs: { description: 'Disallow magic numbers', - recommended: false, extendsBaseRule: true, }, schema: [schema], diff --git a/packages/eslint-plugin/src/rules/no-misused-new.ts b/packages/eslint-plugin/src/rules/no-misused-new.ts index 236d1c544f9..e435b55f5dd 100644 --- a/packages/eslint-plugin/src/rules/no-misused-new.ts +++ b/packages/eslint-plugin/src/rules/no-misused-new.ts @@ -9,7 +9,7 @@ export default util.createRule({ type: 'problem', docs: { description: 'Enforce valid definition of `new` and `constructor`', - recommended: 'error', + recommended: 'recommended', }, schema: [], messages: { diff --git a/packages/eslint-plugin/src/rules/no-misused-promises.ts b/packages/eslint-plugin/src/rules/no-misused-promises.ts index b26f638743a..400778454a9 100644 --- a/packages/eslint-plugin/src/rules/no-misused-promises.ts +++ b/packages/eslint-plugin/src/rules/no-misused-promises.ts @@ -63,7 +63,7 @@ export default util.createRule({ meta: { docs: { description: 'Disallow Promises in places not designed to handle them', - recommended: 'error', + recommended: 'recommended', requiresTypeChecking: true, }, messages: { diff --git a/packages/eslint-plugin/src/rules/no-namespace.ts b/packages/eslint-plugin/src/rules/no-namespace.ts index 40920077ab4..28706e2e0b6 100644 --- a/packages/eslint-plugin/src/rules/no-namespace.ts +++ b/packages/eslint-plugin/src/rules/no-namespace.ts @@ -17,7 +17,7 @@ export default util.createRule({ type: 'suggestion', docs: { description: 'Disallow TypeScript namespaces', - recommended: 'error', + recommended: 'recommended', }, messages: { moduleSyntaxIsPreferred: diff --git a/packages/eslint-plugin/src/rules/no-non-null-asserted-optional-chain.ts b/packages/eslint-plugin/src/rules/no-non-null-asserted-optional-chain.ts index 27675423e11..3939fbdebb2 100644 --- a/packages/eslint-plugin/src/rules/no-non-null-asserted-optional-chain.ts +++ b/packages/eslint-plugin/src/rules/no-non-null-asserted-optional-chain.ts @@ -9,7 +9,7 @@ export default util.createRule({ docs: { description: 'Disallow non-null assertions after an optional chain expression', - recommended: 'error', + recommended: 'recommended', }, hasSuggestions: true, messages: { diff --git a/packages/eslint-plugin/src/rules/no-non-null-assertion.ts b/packages/eslint-plugin/src/rules/no-non-null-assertion.ts index 7a11802a737..b997e6fde3f 100644 --- a/packages/eslint-plugin/src/rules/no-non-null-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-non-null-assertion.ts @@ -12,7 +12,7 @@ export default util.createRule<[], MessageIds>({ docs: { description: 'Disallow non-null assertions using the `!` postfix operator', - recommended: 'warn', + recommended: 'strict', }, hasSuggestions: true, messages: { diff --git a/packages/eslint-plugin/src/rules/no-redeclare.ts b/packages/eslint-plugin/src/rules/no-redeclare.ts index 5d223a35c47..395a9e5b1bc 100644 --- a/packages/eslint-plugin/src/rules/no-redeclare.ts +++ b/packages/eslint-plugin/src/rules/no-redeclare.ts @@ -17,7 +17,6 @@ export default util.createRule({ type: 'suggestion', docs: { description: 'Disallow variable redeclaration', - recommended: false, extendsBaseRule: true, }, schema: [ diff --git a/packages/eslint-plugin/src/rules/no-redundant-type-constituents.ts b/packages/eslint-plugin/src/rules/no-redundant-type-constituents.ts index b19186fc8cd..d5a7f957269 100644 --- a/packages/eslint-plugin/src/rules/no-redundant-type-constituents.ts +++ b/packages/eslint-plugin/src/rules/no-redundant-type-constituents.ts @@ -178,7 +178,6 @@ export default util.createRule({ docs: { description: 'Disallow members of unions and intersections that do nothing or override type information', - recommended: false, requiresTypeChecking: true, }, messages: { diff --git a/packages/eslint-plugin/src/rules/no-require-imports.ts b/packages/eslint-plugin/src/rules/no-require-imports.ts index 9abe1250406..2f9310b38fc 100644 --- a/packages/eslint-plugin/src/rules/no-require-imports.ts +++ b/packages/eslint-plugin/src/rules/no-require-imports.ts @@ -9,7 +9,6 @@ export default util.createRule({ type: 'problem', docs: { description: 'Disallow invocation of `require()`', - recommended: false, }, schema: [], messages: { diff --git a/packages/eslint-plugin/src/rules/no-restricted-imports.ts b/packages/eslint-plugin/src/rules/no-restricted-imports.ts index c2c2b54aa72..48bf8f55c2d 100644 --- a/packages/eslint-plugin/src/rules/no-restricted-imports.ts +++ b/packages/eslint-plugin/src/rules/no-restricted-imports.ts @@ -110,7 +110,6 @@ export default createRule({ type: 'suggestion', docs: { description: 'Disallow specified modules when loaded by `import`', - recommended: false, extendsBaseRule: true, }, messages: baseRule.meta.messages, diff --git a/packages/eslint-plugin/src/rules/no-shadow.ts b/packages/eslint-plugin/src/rules/no-shadow.ts index e9b73370966..991beb9f1eb 100644 --- a/packages/eslint-plugin/src/rules/no-shadow.ts +++ b/packages/eslint-plugin/src/rules/no-shadow.ts @@ -33,7 +33,6 @@ export default util.createRule({ docs: { description: 'Disallow variable declarations from shadowing variables declared in the outer scope', - recommended: false, extendsBaseRule: true, }, schema: [ diff --git a/packages/eslint-plugin/src/rules/no-this-alias.ts b/packages/eslint-plugin/src/rules/no-this-alias.ts index 2301bf11a99..49010d9579e 100644 --- a/packages/eslint-plugin/src/rules/no-this-alias.ts +++ b/packages/eslint-plugin/src/rules/no-this-alias.ts @@ -17,7 +17,7 @@ export default util.createRule({ type: 'suggestion', docs: { description: 'Disallow aliasing `this`', - recommended: 'error', + recommended: 'recommended', }, schema: [ { diff --git a/packages/eslint-plugin/src/rules/no-type-alias.ts b/packages/eslint-plugin/src/rules/no-type-alias.ts index f1faa8dc678..3a29daaf09a 100644 --- a/packages/eslint-plugin/src/rules/no-type-alias.ts +++ b/packages/eslint-plugin/src/rules/no-type-alias.ts @@ -47,7 +47,6 @@ export default util.createRule({ docs: { description: 'Disallow type aliases', // too opinionated to be recommended - recommended: false, }, messages: { noTypeAlias: 'Type {{alias}} are not allowed.', diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-qualifier.ts b/packages/eslint-plugin/src/rules/no-unnecessary-qualifier.ts index 34675bc4f8e..57c6a4fd605 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-qualifier.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-qualifier.ts @@ -10,7 +10,6 @@ export default util.createRule({ meta: { docs: { description: 'Disallow unnecessary namespace qualifiers', - recommended: false, requiresTypeChecking: true, }, fixable: 'code', diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts b/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts index c484fe633f0..3d38a30e32c 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-type-assertion.ts @@ -18,7 +18,7 @@ export default util.createRule({ docs: { description: 'Disallow type assertions that do not change the type of an expression', - recommended: 'error', + recommended: 'recommended', requiresTypeChecking: true, }, fixable: 'code', diff --git a/packages/eslint-plugin/src/rules/no-unnecessary-type-constraint.ts b/packages/eslint-plugin/src/rules/no-unnecessary-type-constraint.ts index 4e4547e2ffb..246d44af6f3 100644 --- a/packages/eslint-plugin/src/rules/no-unnecessary-type-constraint.ts +++ b/packages/eslint-plugin/src/rules/no-unnecessary-type-constraint.ts @@ -16,7 +16,7 @@ export default util.createRule({ meta: { docs: { description: 'Disallow unnecessary constraints on generic types', - recommended: 'error', + recommended: 'recommended', }, hasSuggestions: true, messages: { diff --git a/packages/eslint-plugin/src/rules/no-unsafe-argument.ts b/packages/eslint-plugin/src/rules/no-unsafe-argument.ts index 76fe8652966..cd925691288 100644 --- a/packages/eslint-plugin/src/rules/no-unsafe-argument.ts +++ b/packages/eslint-plugin/src/rules/no-unsafe-argument.ts @@ -137,7 +137,7 @@ export default util.createRule<[], MessageIds>({ type: 'problem', docs: { description: 'Disallow calling a function with a value with type `any`', - recommended: 'error', + recommended: 'recommended', requiresTypeChecking: true, }, messages: { diff --git a/packages/eslint-plugin/src/rules/no-unsafe-assignment.ts b/packages/eslint-plugin/src/rules/no-unsafe-assignment.ts index ec7660d4f22..b9ce9f49ad8 100644 --- a/packages/eslint-plugin/src/rules/no-unsafe-assignment.ts +++ b/packages/eslint-plugin/src/rules/no-unsafe-assignment.ts @@ -22,7 +22,7 @@ export default util.createRule({ docs: { description: 'Disallow assigning a value with type `any` to variables and properties', - recommended: 'error', + recommended: 'recommended', requiresTypeChecking: true, }, messages: { diff --git a/packages/eslint-plugin/src/rules/no-unsafe-call.ts b/packages/eslint-plugin/src/rules/no-unsafe-call.ts index 6bee1215694..d7fe95aa2fc 100644 --- a/packages/eslint-plugin/src/rules/no-unsafe-call.ts +++ b/packages/eslint-plugin/src/rules/no-unsafe-call.ts @@ -16,7 +16,7 @@ export default util.createRule<[], MessageIds>({ type: 'problem', docs: { description: 'Disallow calling a value with type `any`', - recommended: 'error', + recommended: 'recommended', requiresTypeChecking: true, }, messages: { diff --git a/packages/eslint-plugin/src/rules/no-unsafe-member-access.ts b/packages/eslint-plugin/src/rules/no-unsafe-member-access.ts index ca9174b99be..345d1c744cf 100644 --- a/packages/eslint-plugin/src/rules/no-unsafe-member-access.ts +++ b/packages/eslint-plugin/src/rules/no-unsafe-member-access.ts @@ -16,7 +16,7 @@ export default util.createRule({ type: 'problem', docs: { description: 'Disallow member access on a value with type `any`', - recommended: 'error', + recommended: 'recommended', requiresTypeChecking: true, }, messages: { diff --git a/packages/eslint-plugin/src/rules/no-unsafe-return.ts b/packages/eslint-plugin/src/rules/no-unsafe-return.ts index 033aec99c9a..960f91468c5 100644 --- a/packages/eslint-plugin/src/rules/no-unsafe-return.ts +++ b/packages/eslint-plugin/src/rules/no-unsafe-return.ts @@ -11,7 +11,7 @@ export default util.createRule({ type: 'problem', docs: { description: 'Disallow returning a value with type `any` from a function', - recommended: 'error', + recommended: 'recommended', requiresTypeChecking: true, }, messages: { diff --git a/packages/eslint-plugin/src/rules/no-unused-expressions.ts b/packages/eslint-plugin/src/rules/no-unused-expressions.ts index 0ad71a47fba..d5eb14c9350 100644 --- a/packages/eslint-plugin/src/rules/no-unused-expressions.ts +++ b/packages/eslint-plugin/src/rules/no-unused-expressions.ts @@ -15,7 +15,6 @@ export default util.createRule({ type: 'suggestion', docs: { description: 'Disallow unused expressions', - recommended: false, extendsBaseRule: true, }, hasSuggestions: baseRule.meta.hasSuggestions, diff --git a/packages/eslint-plugin/src/rules/no-unused-vars.ts b/packages/eslint-plugin/src/rules/no-unused-vars.ts index 32dd872e543..edb07bce0cc 100644 --- a/packages/eslint-plugin/src/rules/no-unused-vars.ts +++ b/packages/eslint-plugin/src/rules/no-unused-vars.ts @@ -37,7 +37,7 @@ export default util.createRule({ type: 'problem', docs: { description: 'Disallow unused variables', - recommended: 'warn', + recommended: 'recommended', extendsBaseRule: true, }, schema: [ diff --git a/packages/eslint-plugin/src/rules/no-use-before-define.ts b/packages/eslint-plugin/src/rules/no-use-before-define.ts index e723a2cbb18..eccbb320db3 100644 --- a/packages/eslint-plugin/src/rules/no-use-before-define.ts +++ b/packages/eslint-plugin/src/rules/no-use-before-define.ts @@ -242,7 +242,6 @@ export default util.createRule({ type: 'problem', docs: { description: 'Disallow the use of variables before they are defined', - recommended: false, extendsBaseRule: true, }, messages: { diff --git a/packages/eslint-plugin/src/rules/no-useless-empty-export.ts b/packages/eslint-plugin/src/rules/no-useless-empty-export.ts index e671fbf5b1d..7c2b8ca3ea2 100644 --- a/packages/eslint-plugin/src/rules/no-useless-empty-export.ts +++ b/packages/eslint-plugin/src/rules/no-useless-empty-export.ts @@ -29,7 +29,6 @@ export default util.createRule({ docs: { description: "Disallow empty exports that don't change anything in a module file", - recommended: false, }, fixable: 'code', hasSuggestions: false, diff --git a/packages/eslint-plugin/src/rules/no-var-requires.ts b/packages/eslint-plugin/src/rules/no-var-requires.ts index dedc42cf30f..b8655d049d3 100644 --- a/packages/eslint-plugin/src/rules/no-var-requires.ts +++ b/packages/eslint-plugin/src/rules/no-var-requires.ts @@ -12,7 +12,7 @@ export default util.createRule({ type: 'problem', docs: { description: 'Disallow `require` statements except in import statements', - recommended: 'error', + recommended: 'recommended', }, messages: { noVarReqs: 'Require statement not part of import statement.', diff --git a/packages/eslint-plugin/src/rules/non-nullable-type-assertion-style.ts b/packages/eslint-plugin/src/rules/non-nullable-type-assertion-style.ts index 70b25645524..36d6d7bd819 100644 --- a/packages/eslint-plugin/src/rules/non-nullable-type-assertion-style.ts +++ b/packages/eslint-plugin/src/rules/non-nullable-type-assertion-style.ts @@ -10,7 +10,7 @@ export default util.createRule({ meta: { docs: { description: 'Enforce non-null assertions over explicit type casts', - recommended: 'strict', + recommended: 'stylistic', requiresTypeChecking: true, }, fixable: 'code', diff --git a/packages/eslint-plugin/src/rules/object-curly-spacing.ts b/packages/eslint-plugin/src/rules/object-curly-spacing.ts index 1c1c737c842..c448af3702c 100644 --- a/packages/eslint-plugin/src/rules/object-curly-spacing.ts +++ b/packages/eslint-plugin/src/rules/object-curly-spacing.ts @@ -25,7 +25,6 @@ export default createRule({ ...baseRule.meta, docs: { description: 'Enforce consistent spacing inside braces', - recommended: false, extendsBaseRule: true, }, }, diff --git a/packages/eslint-plugin/src/rules/padding-line-between-statements.ts b/packages/eslint-plugin/src/rules/padding-line-between-statements.ts index f9b97096afc..7cadfac4613 100644 --- a/packages/eslint-plugin/src/rules/padding-line-between-statements.ts +++ b/packages/eslint-plugin/src/rules/padding-line-between-statements.ts @@ -590,7 +590,6 @@ export default util.createRule({ type: 'layout', docs: { description: 'Require or disallow padding lines between statements', - recommended: false, extendsBaseRule: true, }, fixable: 'whitespace', diff --git a/packages/eslint-plugin/src/rules/parameter-properties.ts b/packages/eslint-plugin/src/rules/parameter-properties.ts index 32547d9650f..2d75a9c7b6e 100644 --- a/packages/eslint-plugin/src/rules/parameter-properties.ts +++ b/packages/eslint-plugin/src/rules/parameter-properties.ts @@ -30,7 +30,6 @@ export default util.createRule({ docs: { description: 'Require or disallow parameter properties in class constructors', - recommended: false, }, messages: { preferClassProperty: diff --git a/packages/eslint-plugin/src/rules/prefer-as-const.ts b/packages/eslint-plugin/src/rules/prefer-as-const.ts index 00d1250d9ac..5372e0ed3b0 100644 --- a/packages/eslint-plugin/src/rules/prefer-as-const.ts +++ b/packages/eslint-plugin/src/rules/prefer-as-const.ts @@ -9,7 +9,7 @@ export default util.createRule({ type: 'suggestion', docs: { description: 'Enforce the use of `as const` over literal type', - recommended: 'error', + recommended: 'recommended', }, fixable: 'code', hasSuggestions: true, diff --git a/packages/eslint-plugin/src/rules/prefer-enum-initializers.ts b/packages/eslint-plugin/src/rules/prefer-enum-initializers.ts index c852d9fdd57..50ce4a7de6b 100644 --- a/packages/eslint-plugin/src/rules/prefer-enum-initializers.ts +++ b/packages/eslint-plugin/src/rules/prefer-enum-initializers.ts @@ -11,7 +11,6 @@ export default util.createRule<[], MessageIds>({ docs: { description: 'Require each enum member value to be explicitly initialized', - recommended: false, }, hasSuggestions: true, messages: { diff --git a/packages/eslint-plugin/src/rules/prefer-for-of.ts b/packages/eslint-plugin/src/rules/prefer-for-of.ts index ddde074a234..d326b1114fd 100644 --- a/packages/eslint-plugin/src/rules/prefer-for-of.ts +++ b/packages/eslint-plugin/src/rules/prefer-for-of.ts @@ -10,7 +10,7 @@ export default util.createRule({ docs: { description: 'Enforce the use of `for-of` loop over the standard `for` loop where possible', - recommended: 'strict', + recommended: 'stylistic', }, messages: { preferForOf: diff --git a/packages/eslint-plugin/src/rules/prefer-function-type.ts b/packages/eslint-plugin/src/rules/prefer-function-type.ts index 75a886b9760..23bbb71f02f 100644 --- a/packages/eslint-plugin/src/rules/prefer-function-type.ts +++ b/packages/eslint-plugin/src/rules/prefer-function-type.ts @@ -14,7 +14,7 @@ export default util.createRule({ docs: { description: 'Enforce using function types instead of interfaces with call signatures', - recommended: 'strict', + recommended: 'stylistic', }, fixable: 'code', messages: { diff --git a/packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts b/packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts index b40b62f3815..1aa0919d04b 100644 --- a/packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts +++ b/packages/eslint-plugin/src/rules/prefer-namespace-keyword.ts @@ -9,7 +9,7 @@ export default util.createRule({ docs: { description: 'Require using `namespace` keyword over `module` keyword to declare custom TypeScript modules', - recommended: 'error', + recommended: 'stylistic', }, fixable: 'code', messages: { diff --git a/packages/eslint-plugin/src/rules/prefer-nullish-coalescing.ts b/packages/eslint-plugin/src/rules/prefer-nullish-coalescing.ts index d4078a87e06..58ead7e4b7a 100644 --- a/packages/eslint-plugin/src/rules/prefer-nullish-coalescing.ts +++ b/packages/eslint-plugin/src/rules/prefer-nullish-coalescing.ts @@ -27,7 +27,7 @@ export default util.createRule({ docs: { description: 'Enforce using the nullish coalescing operator instead of logical assignments or chaining', - recommended: 'strict', + recommended: 'stylistic', requiresTypeChecking: true, }, hasSuggestions: true, diff --git a/packages/eslint-plugin/src/rules/prefer-optional-chain.ts b/packages/eslint-plugin/src/rules/prefer-optional-chain.ts index 767c235ec08..f3cbeb3b842 100644 --- a/packages/eslint-plugin/src/rules/prefer-optional-chain.ts +++ b/packages/eslint-plugin/src/rules/prefer-optional-chain.ts @@ -37,7 +37,7 @@ export default util.createRule({ docs: { description: 'Enforce using concise optional chain expressions instead of chained logical ands, negated logical ors, or empty objects', - recommended: 'strict', + recommended: 'stylistic', }, hasSuggestions: true, messages: { diff --git a/packages/eslint-plugin/src/rules/prefer-readonly-parameter-types.ts b/packages/eslint-plugin/src/rules/prefer-readonly-parameter-types.ts index 02e249a5f7b..af83179904d 100644 --- a/packages/eslint-plugin/src/rules/prefer-readonly-parameter-types.ts +++ b/packages/eslint-plugin/src/rules/prefer-readonly-parameter-types.ts @@ -18,7 +18,6 @@ export default util.createRule({ docs: { description: 'Require function parameters to be typed as `readonly` to prevent accidental mutation of inputs', - recommended: false, requiresTypeChecking: true, }, schema: [ diff --git a/packages/eslint-plugin/src/rules/prefer-readonly.ts b/packages/eslint-plugin/src/rules/prefer-readonly.ts index 5a22a3f95d7..e91aa5bc8a9 100644 --- a/packages/eslint-plugin/src/rules/prefer-readonly.ts +++ b/packages/eslint-plugin/src/rules/prefer-readonly.ts @@ -26,7 +26,6 @@ export default util.createRule({ docs: { description: "Require private members to be marked as `readonly` if they're never modified outside of the constructor", - recommended: false, requiresTypeChecking: true, }, fixable: 'code', diff --git a/packages/eslint-plugin/src/rules/prefer-regexp-exec.ts b/packages/eslint-plugin/src/rules/prefer-regexp-exec.ts index 4d5b858dc2c..dd185a476a5 100644 --- a/packages/eslint-plugin/src/rules/prefer-regexp-exec.ts +++ b/packages/eslint-plugin/src/rules/prefer-regexp-exec.ts @@ -28,7 +28,6 @@ export default createRule({ docs: { description: 'Enforce `RegExp#exec` over `String#match` if no global flag is provided', - recommended: false, requiresTypeChecking: true, }, messages: { diff --git a/packages/eslint-plugin/src/rules/prefer-string-starts-ends-with.ts b/packages/eslint-plugin/src/rules/prefer-string-starts-ends-with.ts index b35e16c2049..043c27ddbad 100644 --- a/packages/eslint-plugin/src/rules/prefer-string-starts-ends-with.ts +++ b/packages/eslint-plugin/src/rules/prefer-string-starts-ends-with.ts @@ -26,7 +26,7 @@ export default createRule({ docs: { description: 'Enforce using `String#startsWith` and `String#endsWith` over other equivalent methods of checking substrings', - recommended: 'strict', + recommended: 'stylistic', requiresTypeChecking: true, }, messages: { diff --git a/packages/eslint-plugin/src/rules/promise-function-async.ts b/packages/eslint-plugin/src/rules/promise-function-async.ts index 4d708f1f2cd..1c81eec076e 100644 --- a/packages/eslint-plugin/src/rules/promise-function-async.ts +++ b/packages/eslint-plugin/src/rules/promise-function-async.ts @@ -24,7 +24,6 @@ export default util.createRule({ docs: { description: 'Require any function or method that returns a Promise to be marked async', - recommended: false, requiresTypeChecking: true, }, messages: { diff --git a/packages/eslint-plugin/src/rules/quotes.ts b/packages/eslint-plugin/src/rules/quotes.ts index 59f718c50ae..b5f2f7f57b0 100644 --- a/packages/eslint-plugin/src/rules/quotes.ts +++ b/packages/eslint-plugin/src/rules/quotes.ts @@ -16,7 +16,6 @@ export default util.createRule({ docs: { description: 'Enforce the consistent use of either backticks, double, or single quotes', - recommended: false, extendsBaseRule: true, }, fixable: 'code', diff --git a/packages/eslint-plugin/src/rules/require-array-sort-compare.ts b/packages/eslint-plugin/src/rules/require-array-sort-compare.ts index 403e05ab30f..d87c6a06328 100644 --- a/packages/eslint-plugin/src/rules/require-array-sort-compare.ts +++ b/packages/eslint-plugin/src/rules/require-array-sort-compare.ts @@ -22,7 +22,6 @@ export default util.createRule({ docs: { description: 'Require `Array#sort` calls to always provide a `compareFunction`', - recommended: false, requiresTypeChecking: true, }, messages: { diff --git a/packages/eslint-plugin/src/rules/require-await.ts b/packages/eslint-plugin/src/rules/require-await.ts index c70af4e9972..f363c2ee662 100644 --- a/packages/eslint-plugin/src/rules/require-await.ts +++ b/packages/eslint-plugin/src/rules/require-await.ts @@ -23,7 +23,7 @@ export default util.createRule({ type: 'suggestion', docs: { description: 'Disallow async functions which have no `await` expression', - recommended: 'error', + recommended: 'recommended', requiresTypeChecking: true, extendsBaseRule: true, }, diff --git a/packages/eslint-plugin/src/rules/restrict-plus-operands.ts b/packages/eslint-plugin/src/rules/restrict-plus-operands.ts index b1dccf3a7c9..7232d610911 100644 --- a/packages/eslint-plugin/src/rules/restrict-plus-operands.ts +++ b/packages/eslint-plugin/src/rules/restrict-plus-operands.ts @@ -23,7 +23,7 @@ export default util.createRule({ docs: { description: 'Require both operands of addition to be the same type and be `bigint`, `number`, or `string`', - recommended: 'error', + recommended: 'recommended', requiresTypeChecking: true, }, messages: { diff --git a/packages/eslint-plugin/src/rules/restrict-template-expressions.ts b/packages/eslint-plugin/src/rules/restrict-template-expressions.ts index 7a5b1ba286a..89282ea032d 100644 --- a/packages/eslint-plugin/src/rules/restrict-template-expressions.ts +++ b/packages/eslint-plugin/src/rules/restrict-template-expressions.ts @@ -23,7 +23,7 @@ export default util.createRule({ docs: { description: 'Enforce template literal expressions to be of `string` type', - recommended: 'error', + recommended: 'recommended', requiresTypeChecking: true, }, messages: { diff --git a/packages/eslint-plugin/src/rules/return-await.ts b/packages/eslint-plugin/src/rules/return-await.ts index 8bf64156ce6..9fbe9850c68 100644 --- a/packages/eslint-plugin/src/rules/return-await.ts +++ b/packages/eslint-plugin/src/rules/return-await.ts @@ -21,7 +21,6 @@ export default util.createRule({ meta: { docs: { description: 'Enforce consistent returning of awaited values', - recommended: false, requiresTypeChecking: true, extendsBaseRule: 'no-return-await', }, diff --git a/packages/eslint-plugin/src/rules/semi.ts b/packages/eslint-plugin/src/rules/semi.ts index 5fad3f3b395..1719bc24700 100644 --- a/packages/eslint-plugin/src/rules/semi.ts +++ b/packages/eslint-plugin/src/rules/semi.ts @@ -16,7 +16,6 @@ export default util.createRule({ docs: { description: 'Require or disallow semicolons instead of ASI', // too opinionated to be recommended - recommended: false, extendsBaseRule: true, }, fixable: 'code', diff --git a/packages/eslint-plugin/src/rules/sort-type-constituents.ts b/packages/eslint-plugin/src/rules/sort-type-constituents.ts index 848b2ce0722..81af9b1d9ec 100644 --- a/packages/eslint-plugin/src/rules/sort-type-constituents.ts +++ b/packages/eslint-plugin/src/rules/sort-type-constituents.ts @@ -112,7 +112,7 @@ export default util.createRule({ docs: { description: 'Enforce constituents of a type union/intersection to be sorted alphabetically', - recommended: false, + recommended: 'stylistic', }, fixable: 'code', hasSuggestions: true, diff --git a/packages/eslint-plugin/src/rules/space-before-blocks.ts b/packages/eslint-plugin/src/rules/space-before-blocks.ts index 5f16929aa52..4f82bb785a1 100644 --- a/packages/eslint-plugin/src/rules/space-before-blocks.ts +++ b/packages/eslint-plugin/src/rules/space-before-blocks.ts @@ -14,7 +14,6 @@ export default util.createRule({ type: 'layout', docs: { description: 'Enforce consistent spacing before blocks', - recommended: false, extendsBaseRule: true, }, fixable: baseRule.meta.fixable, diff --git a/packages/eslint-plugin/src/rules/space-before-function-paren.ts b/packages/eslint-plugin/src/rules/space-before-function-paren.ts index 4693fee6706..369ae43d880 100644 --- a/packages/eslint-plugin/src/rules/space-before-function-paren.ts +++ b/packages/eslint-plugin/src/rules/space-before-function-paren.ts @@ -22,7 +22,6 @@ export default util.createRule({ type: 'layout', docs: { description: 'Enforce consistent spacing before function parenthesis', - recommended: false, extendsBaseRule: true, }, fixable: 'whitespace', diff --git a/packages/eslint-plugin/src/rules/space-infix-ops.ts b/packages/eslint-plugin/src/rules/space-infix-ops.ts index 678cd2c4c8a..3b83b20e378 100644 --- a/packages/eslint-plugin/src/rules/space-infix-ops.ts +++ b/packages/eslint-plugin/src/rules/space-infix-ops.ts @@ -16,7 +16,6 @@ export default util.createRule({ type: 'layout', docs: { description: 'Require spacing around infix operators', - recommended: false, extendsBaseRule: true, }, fixable: baseRule.meta.fixable, diff --git a/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts b/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts index 43802acf1ee..111fcca5e64 100644 --- a/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts +++ b/packages/eslint-plugin/src/rules/strict-boolean-expressions.ts @@ -55,7 +55,6 @@ export default util.createRule({ hasSuggestions: true, docs: { description: 'Disallow certain types in boolean expressions', - recommended: false, requiresTypeChecking: true, }, schema: [ diff --git a/packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts b/packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts index 6f85e4818ea..420a60f03d7 100644 --- a/packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts +++ b/packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts @@ -18,7 +18,6 @@ export default createRule({ docs: { description: 'Require switch-case statements to be exhaustive with union type', - recommended: false, requiresTypeChecking: true, }, hasSuggestions: true, diff --git a/packages/eslint-plugin/src/rules/triple-slash-reference.ts b/packages/eslint-plugin/src/rules/triple-slash-reference.ts index 4425e666338..0eef1368505 100644 --- a/packages/eslint-plugin/src/rules/triple-slash-reference.ts +++ b/packages/eslint-plugin/src/rules/triple-slash-reference.ts @@ -19,7 +19,7 @@ export default util.createRule({ docs: { description: 'Disallow certain triple slash directives in favor of ES6-style import declarations', - recommended: 'error', + recommended: 'recommended', }, messages: { tripleSlashReference: diff --git a/packages/eslint-plugin/src/rules/type-annotation-spacing.ts b/packages/eslint-plugin/src/rules/type-annotation-spacing.ts index cdc77c22903..37d7b18d635 100644 --- a/packages/eslint-plugin/src/rules/type-annotation-spacing.ts +++ b/packages/eslint-plugin/src/rules/type-annotation-spacing.ts @@ -115,7 +115,6 @@ export default util.createRule({ type: 'layout', docs: { description: 'Require consistent spacing around type annotations', - recommended: false, }, fixable: 'whitespace', messages: { diff --git a/packages/eslint-plugin/src/rules/typedef.ts b/packages/eslint-plugin/src/rules/typedef.ts index 0673566875c..bc95283b78c 100644 --- a/packages/eslint-plugin/src/rules/typedef.ts +++ b/packages/eslint-plugin/src/rules/typedef.ts @@ -23,7 +23,6 @@ export default util.createRule<[Options], MessageIds>({ meta: { docs: { description: 'Require type annotations in certain places', - recommended: false, }, messages: { expectedTypedef: 'Expected a type annotation.', diff --git a/packages/eslint-plugin/src/rules/unbound-method.ts b/packages/eslint-plugin/src/rules/unbound-method.ts index 966664d9d6a..93aaddf1a79 100644 --- a/packages/eslint-plugin/src/rules/unbound-method.ts +++ b/packages/eslint-plugin/src/rules/unbound-method.ts @@ -130,7 +130,7 @@ export default util.createRule({ docs: { description: 'Enforce unbound methods are called with their expected scope', - recommended: 'error', + recommended: 'recommended', requiresTypeChecking: true, }, messages: { diff --git a/packages/eslint-plugin/tests/configs.test.ts b/packages/eslint-plugin/tests/configs.test.ts index a52f1d93ace..4fcc7d0d5d0 100644 --- a/packages/eslint-plugin/tests/configs.test.ts +++ b/packages/eslint-plugin/tests/configs.test.ts @@ -1,3 +1,5 @@ +import type { RuleRecommendation } from '@typescript-eslint/utils/src/ts-eslint'; + import plugin from '../src/index'; import rules from '../src/rules'; @@ -27,6 +29,36 @@ function filterRules(values: Record): [string, string][] { ); } +interface FilterAndMapRuleConfigsSettings { + excludeDeprecated?: boolean; + excludeTypeChecked?: boolean; + recommendations?: (RuleRecommendation | undefined)[]; +} + +function filterAndMapRuleConfigs({ + excludeDeprecated, + excludeTypeChecked, + recommendations, +}: FilterAndMapRuleConfigsSettings = {}): [string, string][] { + let result = Object.entries(rules); + + if (excludeDeprecated) { + result = result.filter(([, rule]) => !rule.meta.deprecated); + } + + if (excludeTypeChecked) { + result = result.filter(([, rule]) => !rule.meta.docs?.requiresTypeChecking); + } + + if (recommendations) { + result = result.filter(([, rule]) => + recommendations.includes(rule.meta.docs?.recommended), + ); + } + + return result.map(([name]) => [`${RULE_NAME_PREFIX}${name}`, 'error']); +} + function itHasBaseRulesOverriden( unfilteredConfigRules: Record, ): void { @@ -44,79 +76,122 @@ function itHasBaseRulesOverriden( }); } -describe('all.json config', () => { +describe('all.ts', () => { const unfilteredConfigRules: Record = plugin.configs.all.rules; - const configRules = filterRules(unfilteredConfigRules); - // note: exclude deprecated rules, this config is allowed to change between minor versions - const ruleConfigs = Object.entries(rules) - .filter(([, rule]) => !rule.meta.deprecated) - .map<[string, string]>(([name]) => [`${RULE_NAME_PREFIX}${name}`, 'error']); - it('contains all of the rules, excluding the deprecated ones', () => { + it('contains all of the rules', () => { + const configRules = filterRules(unfilteredConfigRules); + // note: exclude deprecated rules, this config is allowed to change between minor versions + const ruleConfigs = filterAndMapRuleConfigs({ + excludeDeprecated: true, + }); + expect(entriesToObject(ruleConfigs)).toEqual(entriesToObject(configRules)); }); itHasBaseRulesOverriden(unfilteredConfigRules); }); -describe('recommended.json config', () => { +describe('recommended.ts', () => { const unfilteredConfigRules: Record = plugin.configs.recommended.rules; - const configRules = filterRules(unfilteredConfigRules); - // note: include deprecated rules so that the config doesn't change between major bumps - const ruleConfigs = Object.entries(rules) - .filter( - ([, rule]) => - rule.meta.docs?.recommended && - rule.meta.docs.recommended !== 'strict' && - rule.meta.docs?.requiresTypeChecking !== true, - ) - .map<[string, string]>(([name, rule]) => [ - `${RULE_NAME_PREFIX}${name}`, - rule.meta.docs?.recommended ? rule.meta.docs.recommended : 'off', - ]); - - it("contains all recommended rules that don't require typechecking, excluding the deprecated ones", () => { + + it('contains all recommended rules, excluding type checked ones', () => { + const configRules = filterRules(unfilteredConfigRules); + // note: include deprecated rules so that the config doesn't change between major bumps + const ruleConfigs = filterAndMapRuleConfigs({ + excludeTypeChecked: true, + recommendations: ['recommended'], + }); + expect(entriesToObject(ruleConfigs)).toEqual(entriesToObject(configRules)); }); itHasBaseRulesOverriden(unfilteredConfigRules); }); -describe('recommended-requiring-type-checking.json config', () => { +describe('recommended-type-checked.ts', () => { const unfilteredConfigRules: Record = - plugin.configs['recommended-requiring-type-checking'].rules; - const configRules = filterRules(unfilteredConfigRules); - // note: include deprecated rules so that the config doesn't change between major bumps - const ruleConfigs = Object.entries(rules) - .filter( - ([, rule]) => - rule.meta.docs?.recommended && - rule.meta.docs.recommended !== 'strict' && - rule.meta.docs.requiresTypeChecking === true, - ) - .map<[string, string]>(([name, rule]) => [ - `${RULE_NAME_PREFIX}${name}`, - rule.meta.docs?.recommended ? rule.meta.docs.recommended : 'off', - ]); - - it('contains all recommended rules that require type checking, excluding the deprecated ones', () => { + plugin.configs['recommended-type-checked'].rules; + + it('contains all recommended rules', () => { + const configRules = filterRules(unfilteredConfigRules); + // note: include deprecated rules so that the config doesn't change between major bumps + const ruleConfigs = filterAndMapRuleConfigs({ + recommendations: ['recommended'], + }); + expect(entriesToObject(ruleConfigs)).toEqual(entriesToObject(configRules)); }); itHasBaseRulesOverriden(unfilteredConfigRules); }); -describe('strict.json config', () => { +describe('strict.ts', () => { const unfilteredConfigRules: Record = plugin.configs['strict'].rules; + + it('contains all strict rules, excluding type checked ones', () => { + const configRules = filterRules(unfilteredConfigRules); + // note: exclude deprecated rules, this config is allowed to change between minor versions + const ruleConfigs = filterAndMapRuleConfigs({ + excludeDeprecated: true, + excludeTypeChecked: true, + recommendations: ['recommended', 'strict'], + }); + + expect(entriesToObject(ruleConfigs)).toEqual(entriesToObject(configRules)); + }); + + itHasBaseRulesOverriden(unfilteredConfigRules); +}); + +describe('strict-type-checked.ts', () => { + const unfilteredConfigRules: Record = + plugin.configs['strict-type-checked'].rules; + + it('contains all strict rules', () => { + const configRules = filterRules(unfilteredConfigRules); + // note: exclude deprecated rules, this config is allowed to change between minor versions + const ruleConfigs = filterAndMapRuleConfigs({ + excludeDeprecated: true, + recommendations: ['recommended', 'strict'], + }); + expect(entriesToObject(ruleConfigs)).toEqual(entriesToObject(configRules)); + }); + + itHasBaseRulesOverriden(unfilteredConfigRules); +}); + +describe('stylistic.ts', () => { + const unfilteredConfigRules: Record = + plugin.configs['stylistic'].rules; + + it('contains all stylistic rules, excluding deprecated or type checked ones', () => { + const configRules = filterRules(unfilteredConfigRules); + // note: include deprecated rules so that the config doesn't change between major bumps + const ruleConfigs = filterAndMapRuleConfigs({ + excludeTypeChecked: true, + recommendations: ['stylistic'], + }); + + expect(entriesToObject(ruleConfigs)).toEqual(entriesToObject(configRules)); + }); + + itHasBaseRulesOverriden(unfilteredConfigRules); +}); + +describe('stylistic-type-checked.ts', () => { + const unfilteredConfigRules: Record = + plugin.configs['stylistic-type-checked'].rules; const configRules = filterRules(unfilteredConfigRules); - const ruleConfigs = Object.entries(rules) - .filter(([, rule]) => rule.meta.docs?.recommended === 'strict') - .map<[string, string]>(([name]) => [`${RULE_NAME_PREFIX}${name}`, 'warn']); + // note: include deprecated rules so that the config doesn't change between major bumps + const ruleConfigs = filterAndMapRuleConfigs({ + recommendations: ['stylistic'], + }); - it('contains all recommended rules that require type checking, excluding the deprecated ones', () => { + it('contains all stylistic rules, excluding deprecated ones', () => { expect(entriesToObject(ruleConfigs)).toEqual(entriesToObject(configRules)); }); diff --git a/packages/eslint-plugin/tests/index.test.ts b/packages/eslint-plugin/tests/index.test.ts index 3cac8304e9c..9d791a99beb 100644 --- a/packages/eslint-plugin/tests/index.test.ts +++ b/packages/eslint-plugin/tests/index.test.ts @@ -19,6 +19,10 @@ describe('eslint-plugin ("./src/index.ts")', () => { }); it('exports all available configs', () => { - expect(configs).toEqual(expect.arrayContaining(eslintPluginConfigKeys)); + expect([ + ...configs, + // This config is deprecated eventually will be removed + 'recommended-requiring-type-checking', + ]).toEqual(expect.arrayContaining(eslintPluginConfigKeys)); }); }); diff --git a/packages/eslint-plugin/tests/util/getWrappingFixer.test.ts b/packages/eslint-plugin/tests/util/getWrappingFixer.test.ts index 2c7b7977ffb..9b4c070ec61 100644 --- a/packages/eslint-plugin/tests/util/getWrappingFixer.test.ts +++ b/packages/eslint-plugin/tests/util/getWrappingFixer.test.ts @@ -11,7 +11,6 @@ const rule = createRule({ fixable: 'code', docs: { description: 'Add void operator in random places for test purposes.', - recommended: false, }, messages: { addVoid: 'Please void this', diff --git a/packages/eslint-plugin/tests/util/isNodeEqual.test.ts b/packages/eslint-plugin/tests/util/isNodeEqual.test.ts index f087ddbddcd..5e273bb1c7b 100644 --- a/packages/eslint-plugin/tests/util/isNodeEqual.test.ts +++ b/packages/eslint-plugin/tests/util/isNodeEqual.test.ts @@ -11,7 +11,6 @@ const rule = createRule({ fixable: 'code', docs: { description: 'Remove useless expressions.', - recommended: false, }, messages: { removeExpression: 'Remove useless expression', diff --git a/packages/eslint-plugin/tools/generate-breaking-changes.ts b/packages/eslint-plugin/tools/generate-breaking-changes.ts index 0b7da717287..bb24d0ebbe1 100644 --- a/packages/eslint-plugin/tools/generate-breaking-changes.ts +++ b/packages/eslint-plugin/tools/generate-breaking-changes.ts @@ -1,8 +1,12 @@ -// eslint-disable-next-line @typescript-eslint/consistent-type-imports -type RulesFile = typeof import('../src/rules'); +import { fetch } from 'cross-fetch'; +import { markdownTable } from 'markdown-table'; + +import type RulesFile from '../src/rules'; interface RulesObject { - default: RulesFile; + default: { + default: typeof RulesFile; + }; } async function main(): Promise { @@ -11,8 +15,35 @@ async function main(): Promise { } = // @ts-expect-error -- We don't support ESM imports of local code yet. (await import('../dist/rules/index.js')) as RulesObject; - const { markdownTable } = await import('markdown-table'); - const { fetch } = await import('cross-fetch'); + + // Annotate which rules are new since the last version + async function getNewRulesAsOfMajorVersion( + oldVersion: string, + ): Promise> { + // 1. Get the current list of rules (already done) + const newRuleNames = Object.keys(rules); + + // 2. Retrieve the old version of typescript-eslint from unpkg + const oldUrl = `https://unpkg.com/@typescript-eslint/eslint-plugin@${oldVersion}/dist/configs/all.js`; + const oldFileText = await (await fetch(oldUrl)).text(); + const oldObjectText = oldFileText.substring( + oldFileText.indexOf('{'), + oldFileText.lastIndexOf('}') + 1, + ); + // Normally we wouldn't condone using the 'eval' API... + // But this is an internal-only script and it's the easiest way to convert + // the JS raw text into a runtime object. 🀷 + let oldRulesObject!: { rules: typeof RulesFile }; + eval('oldRulesObject = ' + oldObjectText); + const oldRuleNames = new Set(Object.keys(oldRulesObject.rules)); + + // 3. Get the keys that exist in (1) (new version) and not (2) (old version) + return new Set( + newRuleNames.filter( + newRuleName => !oldRuleNames.has(`@typescript-eslint/${newRuleName}`), + ), + ); + } const newRuleNames = await getNewRulesAsOfMajorVersion('5.0.0'); @@ -33,8 +64,17 @@ async function main(): Promise {
  • πŸ†• = newly added to typescript-eslint
  • -
  • πŸ™… = deprecated in the next major
  • -
  • βž–οΈ = to be removed from the plugin in the next version
  • +
  • πŸ™… = to be deprecated in the next major
  • +
  • πŸ’€ = currently deprecated; to be removed in the next version
  • +
+ + + + TC + Requires type checking? + +
    +
  • πŸ’­ = yes
@@ -43,45 +83,43 @@ async function main(): Promise { Extension rule?
    -
  • β˜‘οΈ = yes
  • +
  • 🧱 = yes
- R + Rec'd Recommended
  • βž• = add to recommended this version
  • -
  • ⚠️ = recommended as warning
  • -
  • πŸ›‘ = recommended as an error
  • βž–οΈ = remove from recommended this version
  • +
  • 🟩 = stays in recommended this version
- RWT - Recommended-requiring-type-checking + Strict + Strict
    -
  • βž• = add to recommended-with-typechecking this version
  • -
  • ⚠️ = recommended as warning
  • -
  • πŸ›‘ = recommended as an error
  • -
  • βž–οΈ = remove from recommended this version
  • +
  • βž• = add to strict this version
  • +
  • βž–οΈ = remove from strict this version
  • +
  • πŸ”΅ = stays in strict this version
- Strict - Strict + Style + Style
    -
  • βž• = add to strict this version
  • -
  • ⚠️ = recommended as warning
  • -
  • βž–οΈ = remove from strict this version
  • +
  • βž• = add to stylistic this version
  • +
  • βž–οΈ = remove from stylistic this version
  • +
  • πŸ”Έ = stays in stylistic this version
- + @@ -92,7 +130,7 @@ async function main(): Promise { console.log( markdownTable([ - ['Rule', 'Status', 'Ext', 'R', 'RWT', 'Strict', 'Comment'], + ['Rule', 'Status', 'TC', 'Ext', "Rec'd", 'Strict', 'Style', 'Comment'], ...Object.entries(rules).map(([ruleName, { meta }]) => { const { deprecated } = meta; const { extendsBaseRule, recommended, requiresTypeChecking } = @@ -100,55 +138,17 @@ async function main(): Promise { return [ `[\`${ruleName}\`](https://typescript-eslint.io/rules/${ruleName})`, - newRuleNames.has(ruleName) ? 'πŸ†•' : deprecated ? 'πŸ™…' : '', - extendsBaseRule ? 'β˜‘οΈ' : '', - recommended && - ['error', 'warn'].includes(recommended) && - !requiresTypeChecking - ? 'πŸ›‘' - : '', - recommended && - ['error', 'warn'].includes(recommended) && - requiresTypeChecking - ? 'πŸ›‘' - : '', - recommended === 'strict' ? '⚠️' : '', + newRuleNames.has(ruleName) ? 'πŸ†•' : deprecated ? 'πŸ’€' : '', + requiresTypeChecking ? 'πŸ’­' : '', + extendsBaseRule ? '🧱' : '', + recommended === 'recommended' ? '🟩' : '', + recommended === 'strict' ? 'πŸ”΅' : '', + recommended === 'stylistic' ? 'πŸ”Έ' : '', meta.type === 'layout' ? 'layout πŸ’©' : '(todo)', ]; }), ]), ); - - // Annotate which rules are new since version 5.0.0 - async function getNewRulesAsOfMajorVersion( - oldVersion: string, - ): Promise> { - // 1. Get the current list of rules (already done) - const newRuleNames = Object.keys(rules); - - // 2. Use some CDN thing for the 5.X version of typescript-eslint - const oldUrl = `https://unpkg.com/@typescript-eslint/eslint-plugin@${oldVersion}/dist/configs/all.js`; - const oldFileText = await (await fetch(oldUrl)).text(); - const oldObjectText = oldFileText.substring( - oldFileText.indexOf('{'), - oldFileText.lastIndexOf('}') + 1, - ); - // Normally we wouldn't condone using the 'eval' API... - // But this is an internal-only script and it's the easiest way to convert - // the JS raw text into a runtime object. 🀷 - let oldRulesObject!: { rules: RulesFile }; - eval('oldRulesObject = ' + oldObjectText); - const oldRuleNames = new Set(Object.keys(oldRulesObject.rules)); - - // 3. Get the keys that exist in (1) (new version) and not (2) (old version) - return new Set( - newRuleNames.filter( - newRuleName => !oldRuleNames.has(`@typescript-eslint/${newRuleName}`), - ), - ); - } - - await getNewRulesAsOfMajorVersion('5.0.0'); } main().catch(error => { diff --git a/packages/eslint-plugin/tools/generate-configs.ts b/packages/eslint-plugin/tools/generate-configs.ts index 30132f9b0f0..1946bee239a 100644 --- a/packages/eslint-plugin/tools/generate-configs.ts +++ b/packages/eslint-plugin/tools/generate-configs.ts @@ -1,247 +1,257 @@ import type { TSESLint } from '@typescript-eslint/utils'; import chalk from 'chalk'; -import fs from 'fs'; -import path from 'path'; -import { format, resolveConfig } from 'prettier'; - -import rules from '../src/rules'; - -function addAutoGeneratedComment(code: string): string { - return [ - '// THIS CODE WAS AUTOMATICALLY GENERATED', - '// DO NOT EDIT THIS CODE BY HAND', - '// YOU CAN REGENERATE IT USING yarn generate:configs', - '', - code, - ].join('\n'); -} +import * as fs from 'fs'; +import * as path from 'path'; +import prettier from 'prettier'; +import * as url from 'url'; -const prettierConfig = resolveConfig.sync(__dirname); +import type RulesFile from '../src/rules'; -interface LinterConfigRules { - [name: string]: - | TSESLint.Linter.RuleLevel - | TSESLint.Linter.RuleLevelAndOptions; +interface RulesObject { + default: { + default: typeof RulesFile; + }; } -interface LinterConfig extends TSESLint.Linter.Config { - extends?: string | string[]; - plugins?: string[]; -} +async function main(): Promise { + // TODO: Standardize & simplify these tools/* scripts once v6 is more stable + // @ts-expect-error -- ts-node allows us to use import.meta + const __dirname = url.fileURLToPath(new URL('.', import.meta.url)); -const RULE_NAME_PREFIX = '@typescript-eslint/'; -const MAX_RULE_NAME_LENGTH = Object.keys(rules).reduce( - (acc, name) => Math.max(acc, name.length), - 0, -); -const DEFAULT_RULE_SETTING = 'warn'; -const BASE_RULES_TO_BE_OVERRIDDEN = new Map( - Object.entries(rules) - .filter(([, rule]) => rule.meta.docs?.extendsBaseRule) - .map( - ([ruleName, rule]) => - [ - ruleName, - typeof rule.meta.docs?.extendsBaseRule === 'string' - ? rule.meta.docs?.extendsBaseRule - : ruleName, - ] as const, - ), -); -const EXTENDS = ['./configs/base', './configs/eslint-recommended']; - -type RuleEntry = [ - string, - TSESLint.RuleModule, -]; - -const ruleEntries: RuleEntry[] = Object.entries(rules).sort((a, b) => - a[0].localeCompare(b[0]), -); - -/** - * Helper function reduces records to key - value pairs. - * @param config - * @param entry - * @param settings - */ -function reducer( - config: LinterConfigRules, - entry: [string, TSESLint.RuleModule], - settings: { - errorLevel?: 'error' | 'warn'; - filterDeprecated: boolean; - filterRequiresTypeChecking?: 'include' | 'exclude'; - }, -): LinterConfigRules { - const key = entry[0]; - const value = entry[1]; - - if (settings.filterDeprecated && value.meta.deprecated) { - return config; + const { + default: { default: rules }, + } = + // @ts-expect-error -- We don't support ESM imports of local code yet. + (await import('../dist/rules/index.js')) as RulesObject; + + function addAutoGeneratedComment(code: string): string { + return [ + '// THIS CODE WAS AUTOMATICALLY GENERATED', + '// DO NOT EDIT THIS CODE BY HAND', + '// SEE https://typescript-eslint.io/linting/configs', + '//', + '// For developers working in the typescript-eslint monorepo:', + '// You can regenerate it using `yarn generate:configs`', + '', + code, + ].join('\n'); } - // Explicitly exclude rules requiring type-checking - if ( - settings.filterRequiresTypeChecking === 'exclude' && - value.meta.docs?.requiresTypeChecking === true - ) { - return config; + const prettierConfig = prettier.resolveConfig.sync(__dirname); + + interface LinterConfigRules { + [name: string]: + | TSESLint.Linter.RuleLevel + | TSESLint.Linter.RuleLevelAndOptions; } - // Explicitly include rules requiring type-checking - if ( - settings.filterRequiresTypeChecking === 'include' && - value.meta.docs?.requiresTypeChecking !== true - ) { - return config; + interface LinterConfig extends TSESLint.Linter.Config { + extends?: string | string[]; + plugins?: string[]; } - const ruleName = `${RULE_NAME_PREFIX}${key}`; - const recommendation = value.meta.docs?.recommended; + const RULE_NAME_PREFIX = '@typescript-eslint/'; + const MAX_RULE_NAME_LENGTH = Object.keys(rules).reduce( + (acc, name) => Math.max(acc, name.length), + 0, + ); + const BASE_RULES_TO_BE_OVERRIDDEN = new Map( + Object.entries(rules) + .filter(([, rule]) => rule.meta.docs?.extendsBaseRule) + .map( + ([ruleName, rule]) => + [ + ruleName, + typeof rule.meta.docs?.extendsBaseRule === 'string' + ? rule.meta.docs?.extendsBaseRule + : ruleName, + ] as const, + ), + ); + const EXTENDS = ['./configs/base', './configs/eslint-recommended']; + + type RuleEntry = [ + string, + TSESLint.RuleModule, + ]; + + const allRuleEntries: RuleEntry[] = Object.entries(rules).sort((a, b) => + a[0].localeCompare(b[0]), + ); + + interface ruleFilter { + deprecated?: 'exclude'; + typeChecked?: 'exclude'; + } - const usedSetting = settings.errorLevel - ? settings.errorLevel - : !recommendation - ? DEFAULT_RULE_SETTING - : recommendation === 'strict' - ? 'warn' - : recommendation; + /** + * Helper function reduces records to key - value pairs. + */ + function reducer( + config: LinterConfigRules, + entry: [string, TSESLint.RuleModule], + settings: ruleFilter = {}, + ): LinterConfigRules { + const key = entry[0]; + const value = entry[1]; - if (BASE_RULES_TO_BE_OVERRIDDEN.has(key)) { - const baseRuleName = BASE_RULES_TO_BE_OVERRIDDEN.get(key)!; + if (settings.deprecated && value.meta.deprecated) { + return config; + } + + // Explicitly exclude rules requiring type-checking + if ( + settings.typeChecked === 'exclude' && + value.meta.docs?.requiresTypeChecking === true + ) { + return config; + } + + const ruleName = `${RULE_NAME_PREFIX}${key}`; + + if (BASE_RULES_TO_BE_OVERRIDDEN.has(key)) { + const baseRuleName = BASE_RULES_TO_BE_OVERRIDDEN.get(key)!; + console.log( + baseRuleName + .padStart(RULE_NAME_PREFIX.length + baseRuleName.length) + .padEnd(RULE_NAME_PREFIX.length + MAX_RULE_NAME_LENGTH), + '=', + chalk.green('off'), + ); + config[baseRuleName] = 'off'; + } console.log( - baseRuleName - .padStart(RULE_NAME_PREFIX.length + baseRuleName.length) - .padEnd(RULE_NAME_PREFIX.length + MAX_RULE_NAME_LENGTH), + `${chalk.dim(RULE_NAME_PREFIX)}${key.padEnd(MAX_RULE_NAME_LENGTH)}`, '=', - chalk.green('off'), + chalk.red('error'), ); - config[baseRuleName] = 'off'; + config[ruleName] = 'error'; + + return config; } - console.log( - `${chalk.dim(RULE_NAME_PREFIX)}${key.padEnd(MAX_RULE_NAME_LENGTH)}`, - '=', - usedSetting === 'error' - ? chalk.red(usedSetting) - : chalk.yellow(usedSetting), - ); - config[ruleName] = usedSetting; - return config; -} + /** + * Helper function writes configuration. + */ + function writeConfig(getConfig: () => LinterConfig, name: string): void { + const hyphens = '-'.repeat(35 - Math.ceil(name.length / 2)); + console.log(chalk.blueBright(`\n${hyphens} ${name}.ts ${hyphens}`)); -/** - * Helper function writes configuration. - */ -function writeConfig(config: LinterConfig, filePath: string): void { - // note: we use `export =` because ESLint will import these configs via a commonjs import - const code = `export = ${JSON.stringify(config)};`; - const configStr = format(addAutoGeneratedComment(code), { - parser: 'typescript', - ...prettierConfig, + // note: we use `export =` because ESLint will import these configs via a commonjs import + const code = `export = ${JSON.stringify(getConfig())};`; + const configStr = prettier.format(addAutoGeneratedComment(code), { + parser: 'typescript', + ...prettierConfig, + }); + fs.writeFileSync( + path.resolve(__dirname, `../src/configs/${name}.ts`), + configStr, + ); + } + + interface ExtendedConfigSettings { + extraExtends?: string[]; + name: string; + filters?: ruleFilter; + ruleEntries: RuleEntry[]; + } + + function writeExtendedConfig({ + extraExtends = [], + filters: ruleFilter, + name, + ruleEntries, + }: ExtendedConfigSettings): void { + writeConfig( + () => ({ + extends: [...EXTENDS, ...extraExtends], + rules: ruleEntries.reduce( + (config, entry) => reducer(config, entry, ruleFilter), + {}, + ), + }), + name, + ); + } + + function filterRuleEntriesTo( + ...recommendations: (TSESLint.RuleRecommendation | undefined)[] + ): RuleEntry[] { + return allRuleEntries.filter(([, rule]) => + recommendations.includes(rule.meta.docs?.recommended), + ); + } + + writeConfig((): LinterConfig => { + const baseConfig: LinterConfig = { + parser: '@typescript-eslint/parser', + parserOptions: { + sourceType: 'module', + }, + plugins: ['@typescript-eslint'], + }; + + console.log(chalk.gray('Config values:')); + + const longestKey = Object.keys(baseConfig).reduce( + (previous, next) => Math.max(previous, next.length), + 0, + ); + for (const [key, value] of Object.entries(baseConfig)) { + console.log(' ', key.padEnd(longestKey), value); + } + + return baseConfig; + }, 'base'); + + writeExtendedConfig({ + name: 'all', + filters: { + deprecated: 'exclude', + }, + ruleEntries: allRuleEntries, + }); + + writeExtendedConfig({ + filters: { + typeChecked: 'exclude', + }, + name: 'recommended', + ruleEntries: filterRuleEntriesTo('recommended'), }); - fs.writeFileSync(filePath, configStr); -} -const recommendedValues = new Set([ - 'error', - 'warn', -]); + writeExtendedConfig({ + name: 'recommended-type-checked', + ruleEntries: filterRuleEntriesTo('recommended'), + }); -function entryIsRecommended(entry: RuleEntry): boolean { - return recommendedValues.has(entry[1].meta.docs?.recommended); -} + writeExtendedConfig({ + filters: { + typeChecked: 'exclude', + }, + name: 'strict', + ruleEntries: filterRuleEntriesTo('recommended', 'strict'), + }); -function entryIsStrict(entry: RuleEntry): boolean { - return entry[1].meta.docs?.recommended === 'strict'; + writeExtendedConfig({ + name: 'strict-type-checked', + ruleEntries: filterRuleEntriesTo('recommended', 'strict'), + }); + + writeExtendedConfig({ + filters: { + typeChecked: 'exclude', + }, + name: 'stylistic', + ruleEntries: filterRuleEntriesTo('stylistic'), + }); + + writeExtendedConfig({ + name: 'stylistic-type-checked', + ruleEntries: filterRuleEntriesTo('stylistic'), + }); } -const baseConfig: LinterConfig = { - parser: '@typescript-eslint/parser', - parserOptions: { - sourceType: 'module', - }, - plugins: ['@typescript-eslint'], -}; -writeConfig(baseConfig, path.resolve(__dirname, '../src/configs/base.ts')); - -console.log(); -console.log( - '------------------------------------------------ all.ts ------------------------------------------------', -); -const allConfig: LinterConfig = { - extends: EXTENDS, - rules: ruleEntries.reduce( - (config, entry) => - reducer(config, entry, { errorLevel: 'error', filterDeprecated: true }), - {}, - ), -}; -writeConfig(allConfig, path.resolve(__dirname, '../src/configs/all.ts')); - -console.log(); -console.log( - '------------------------------ recommended.ts (should not require program) ------------------------------', -); -const recommendedRules = ruleEntries - .filter(entryIsRecommended) - .reduce( - (config, entry) => - reducer(config, entry, { - filterDeprecated: false, - filterRequiresTypeChecking: 'exclude', - }), - {}, - ); -const recommendedConfig: LinterConfig = { - extends: EXTENDS, - rules: recommendedRules, -}; -writeConfig( - recommendedConfig, - path.resolve(__dirname, '../src/configs/recommended.ts'), -); - -console.log(); -console.log( - '--------------------------------- recommended-requiring-type-checking.ts ---------------------------------', -); -const recommendedRulesRequiringProgram = ruleEntries - .filter(entryIsRecommended) - .reduce( - (config, entry) => - reducer(config, entry, { - filterDeprecated: false, - filterRequiresTypeChecking: 'include', - }), - {}, - ); -const recommendedRequiringTypeCheckingConfig: LinterConfig = { - extends: EXTENDS, - rules: recommendedRulesRequiringProgram, -}; -writeConfig( - recommendedRequiringTypeCheckingConfig, - path.resolve( - __dirname, - '../src/configs/recommended-requiring-type-checking.ts', - ), -); - -console.log(); -console.log( - '--------------------------------- strict.ts ---------------------------------', -); -const strictRules = ruleEntries.filter(entryIsStrict).reduce( - (config, entry) => - reducer(config, entry, { - filterDeprecated: false, - }), - {}, -); -const strictConfig: LinterConfig = { - extends: EXTENDS, - rules: strictRules, -}; -writeConfig(strictConfig, path.resolve(__dirname, '../src/configs/strict.ts')); +main().catch(error => { + console.error(error); +}); diff --git a/packages/typescript-estree/src/parser.ts b/packages/typescript-estree/src/parser.ts index 4c08717fbca..65905dbf239 100644 --- a/packages/typescript-estree/src/parser.ts +++ b/packages/typescript-estree/src/parser.ts @@ -80,7 +80,6 @@ function getProgramAndAST( return createNoProgram(parseSettings); } -// eslint-disable-next-line @typescript-eslint/no-empty-interface interface EmptyObject {} type AST = TSESTree.Program & (T['tokens'] extends true ? { tokens: TSESTree.Token[] } : EmptyObject) & diff --git a/packages/typescript-estree/src/ts-estree/ts-nodes.ts b/packages/typescript-estree/src/ts-estree/ts-nodes.ts index 0ba5414e137..4973e4f2a13 100644 --- a/packages/typescript-estree/src/ts-estree/ts-nodes.ts +++ b/packages/typescript-estree/src/ts-estree/ts-nodes.ts @@ -3,7 +3,6 @@ import type * as ts from 'typescript'; // Workaround to support new TS version features for consumers on old TS versions // Eg: https://github.com/typescript-eslint/typescript-eslint/issues/2388, https://github.com/typescript-eslint/typescript-eslint/issues/2784 declare module 'typescript' { - /* eslint-disable @typescript-eslint/no-empty-interface */ // added in TS 4.0 export interface NamedTupleMember extends ts.Node {} // added in TS 4.1 @@ -16,7 +15,6 @@ declare module 'typescript' { export interface AssertEntry extends ts.Node {} // added in TS 4.9 export interface SatisfiesExpression extends ts.Node {} - /* eslint-enable @typescript-eslint/no-empty-interface */ } export type TSToken = ts.Token; diff --git a/packages/utils/src/ts-eslint/Rule.ts b/packages/utils/src/ts-eslint/Rule.ts index a8df03d681e..b0705cc5c47 100644 --- a/packages/utils/src/ts-eslint/Rule.ts +++ b/packages/utils/src/ts-eslint/Rule.ts @@ -5,7 +5,7 @@ import type { Linter } from './Linter'; import type { Scope } from './Scope'; import type { SourceCode } from './SourceCode'; -export type RuleRecommendation = 'error' | 'strict' | 'warn' | false; +export type RuleRecommendation = 'recommended' | 'strict' | 'stylistic'; interface RuleMetaDataDocs { /** @@ -17,7 +17,7 @@ interface RuleMetaDataDocs { * Used by the build tools to generate the recommended and strict configs. * Set to false to not include it as a recommendation */ - recommended: 'error' | 'strict' | 'warn' | false; + recommended?: RuleRecommendation; /** * The URL of the rule's docs */ diff --git a/packages/utils/tests/eslint-utils/RuleCreator.test.ts b/packages/utils/tests/eslint-utils/RuleCreator.test.ts index 5e1c14d68c4..652aa2f1251 100644 --- a/packages/utils/tests/eslint-utils/RuleCreator.test.ts +++ b/packages/utils/tests/eslint-utils/RuleCreator.test.ts @@ -13,7 +13,7 @@ describe('RuleCreator', () => { meta: { docs: { description: 'some description', - recommended: 'error', + recommended: 'recommended', requiresTypeChecking: true, }, messages: { @@ -31,7 +31,7 @@ describe('RuleCreator', () => { docs: { description: 'some description', url: 'test/test', - recommended: 'error', + recommended: 'recommended', requiresTypeChecking: true, }, messages: { diff --git a/packages/website/plugins/generated-rule-docs.ts b/packages/website/plugins/generated-rule-docs.ts index d29d240c91f..d5b9e06335e 100644 --- a/packages/website/plugins/generated-rule-docs.ts +++ b/packages/website/plugins/generated-rule-docs.ts @@ -158,7 +158,6 @@ export const generatedRuleDocs: Plugin = () => { })(); // 5. Add a description of how to use / options for the rule - const optionLevel = meta.docs.recommended === 'error' ? 'error' : 'warn'; if (meta.docs.extendsBaseRule) { const extendsBaseRuleName = @@ -206,7 +205,7 @@ export const generatedRuleDocs: Plugin = () => { : '' } "${extendsBaseRuleName}": "off", - "@typescript-eslint/${file.stem}": "${optionLevel}" + "@typescript-eslint/${file.stem}": "error" } }`; }; @@ -233,7 +232,7 @@ export const generatedRuleDocs: Plugin = () => { const getEslintrcString = `{ "rules": { - "@typescript-eslint/${file.stem}": "${optionLevel}" + "@typescript-eslint/${file.stem}": "error" } }`; root.children.splice(firstH2Index, 0, { diff --git a/packages/website/src/components/RulesTable/index.tsx b/packages/website/src/components/RulesTable/index.tsx index 7b7033abe92..58e9eb6e55c 100644 --- a/packages/website/src/components/RulesTable/index.tsx +++ b/packages/website/src/components/RulesTable/index.tsx @@ -29,17 +29,14 @@ function RuleRow({ rule }: { rule: RulesMeta[number] }): JSX.Element | null {
{interpolateCode(rule.docs.description)} - - {recommended === 'strict' ? 'πŸ”’' : recommended ? 'βœ…' : ''} + + {recommended === 'recommended' + ? 'βœ…' + : recommended === 'strict' + ? 'πŸ”’' + : recommended + ? '🎨' + : ''} ('neutral'); const [showStrict, setShowStrict] = useState('neutral'); + const [showStylistic, setShowStylistic] = useState('neutral'); const [showFixable, setShowFixable] = useState('neutral'); const [showHasSuggestions, setShowHasSuggestion] = useState('neutral'); @@ -135,11 +133,13 @@ export default function RulesTable({ .filter(r => !!extensionRules === !!r.docs?.extendsBaseRule) .filter(r => { const opinions = [ + match(showRecommended, r.docs?.recommended === 'recommended'), match( - showRecommended, - r.docs?.recommended === 'error' || r.docs?.recommended === 'warn', + showStrict, + r.docs?.recommended === 'recommended' || + r.docs?.recommended === 'strict', ), - match(showStrict, r.docs?.recommended === 'strict'), + match(showStylistic, r.docs?.recommended === 'stylistic'), match(showFixable, !!r.fixable), match(showHasSuggestions, !!r.hasSuggestions), match(showTypeCheck, !!r.docs?.requiresTypeChecking), @@ -151,6 +151,7 @@ export default function RulesTable({ extensionRules, showRecommended, showStrict, + showStylistic, showFixable, showHasSuggestions, showTypeCheck, @@ -158,61 +159,53 @@ export default function RulesTable({ ); return ( <> -
    - { - setShowRecommended(newMode); - - if (newMode === 'include' && showStrict === 'include') { - setShowStrict('exclude'); - } - }} - label="βœ… recommended" - /> - { - setShowStrict(newMode); - - if (newMode === 'include' && showRecommended === 'include') { - setShowRecommended('exclude'); - } - }} - label="πŸ”’ strict" - /> - - - -
+
+ Config Group +
    + + + +
+
+
+ Metadata +
    + + + +
+
- - - + + + diff --git a/packages/website/src/components/RulesTable/styles.module.css b/packages/website/src/components/RulesTable/styles.module.css index 4b0d2cd6b63..6f998e88e6a 100644 --- a/packages/website/src/components/RulesTable/styles.module.css +++ b/packages/website/src/components/RulesTable/styles.module.css @@ -17,6 +17,17 @@ --red-border-shadow: rgb(235, 107, 107); } +.checkboxListArea { + display: flex; + align-items: baseline; + gap: 0.5rem; +} + +.checkboxListArea + .checkboxListArea { + margin-top: -0.5rem; + margin-bottom: 0.5rem; +} + .checkboxList { flex-wrap: wrap; } diff --git a/packages/website/src/components/editor/createProvideCodeActions.ts b/packages/website/src/components/editor/createProvideCodeActions.ts index 242d52e3d1e..b537b55a4a5 100644 --- a/packages/website/src/components/editor/createProvideCodeActions.ts +++ b/packages/website/src/components/editor/createProvideCodeActions.ts @@ -11,7 +11,6 @@ export function createProvideCodeActions( model, _range, context, - _token, ): Monaco.languages.ProviderResult { if (context.only !== 'quickfix') { return { diff --git a/packages/website/src/theme/MDXComponents/RuleAttributes.tsx b/packages/website/src/theme/MDXComponents/RuleAttributes.tsx index 572ab28dad8..9094d8a980f 100644 --- a/packages/website/src/theme/MDXComponents/RuleAttributes.tsx +++ b/packages/website/src/theme/MDXComponents/RuleAttributes.tsx @@ -7,12 +7,18 @@ import type { FeatureProps } from './Feature'; import { Feature } from './Feature'; import styles from './RuleAttributes.module.css'; -const getRecommendation = (docs: RuleMetaDataDocs): [string, string] => { - return docs.recommended === 'strict' - ? ['πŸ”’', 'strict'] - : docs.requiresTypeChecking - ? ['🧠', 'recommended-requiring-type-checking'] - : ['βœ…', 'recommended']; +const recommendations = { + recommended: ['βœ…', 'recommended'], + strict: ['πŸ”’', 'strict'], + stylistic: ['🎨', 'stylistic'], +}; + +const getRecommendation = (docs: RuleMetaDataDocs): string[] => { + const recommendation = recommendations[docs.recommended!]; + + return docs.requiresTypeChecking + ? [recommendation[0], `${recommendation[1]}-type-checked`] + : recommendation; }; export function RuleAttributes({ name }: { name: string }): React.ReactNode { diff --git a/tests/integration/tests/__snapshots__/recommended-does-not-require-program.test.ts.snap b/tests/integration/tests/__snapshots__/recommended-does-not-require-program.test.ts.snap index 40e5fd8d3da..db6b4a80644 100644 --- a/tests/integration/tests/__snapshots__/recommended-does-not-require-program.test.ts.snap +++ b/tests/integration/tests/__snapshots__/recommended-does-not-require-program.test.ts.snap @@ -3,7 +3,7 @@ exports[`recommended-does-not-require-program should lint successfully 1`] = ` [ { - "errorCount": 0, + "errorCount": 1, "fatalErrorCount": 0, "filePath": "/index.ts", "fixableErrorCount": 0, @@ -18,49 +18,14 @@ exports[`recommended-does-not-require-program should lint successfully 1`] = ` "messageId": "unusedVar", "nodeType": "Identifier", "ruleId": "@typescript-eslint/no-unused-vars", - "severity": 1, - }, - { - "column": 12, - "endColumn": 15, - "endLine": 1, - "line": 1, - "message": "Unexpected any. Specify a different type.", - "messageId": "unexpectedAny", - "nodeType": "TSAnyKeyword", - "ruleId": "@typescript-eslint/no-explicit-any", - "severity": 1, - "suggestions": [ - { - "desc": "Use \`unknown\` instead, this will force you to explicitly, and safely assert the type is correct.", - "fix": { - "range": [ - 11, - 14, - ], - "text": "unknown", - }, - "messageId": "suggestUnknown", - }, - { - "desc": "Use \`never\` instead, this is useful when instantiating generic type parameters that you don't need to know the type of.", - "fix": { - "range": [ - 11, - 14, - ], - "text": "never", - }, - "messageId": "suggestNever", - }, - ], + "severity": 2, }, ], "output": "const foo: any = true; ", "suppressedMessages": [], "usedDeprecatedRules": [], - "warningCount": 2, + "warningCount": 0, }, ] `; diff --git a/yarn.lock b/yarn.lock index a1b168e17d5..4ab54a03fc5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14133,9 +14133,9 @@ uuid@^8.3.2: integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== v8-compile-cache-lib@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz#0582bcb1c74f3a2ee46487ceecf372e46bce53e8" - integrity sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA== + version "3.0.1" + resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" + integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== v8-compile-cache@2.3.0, v8-compile-cache@^2.0.3: version "2.3.0"
Rule - βœ…{'\n'}πŸ”’ - - πŸ”§{'\n'}πŸ’‘ - - πŸ’­ - ConfigFixerTyped