From 3c6b5945b94d85fce07d7a05d36ac30f0f5cceb1 Mon Sep 17 00:00:00 2001 From: James <5511220+Zamiell@users.noreply.github.com> Date: Sun, 17 Sep 2023 11:28:07 -0400 Subject: [PATCH 01/19] docs: sort rules by extension --- packages/eslint-plugin/docs/rules/README.md | 25 +++-- .../src/components/RulesTable/index.tsx | 101 +++++++++++------- packages/website/src/components/constants.ts | 18 ++++ .../theme/MDXComponents/RuleAttributes.tsx | 17 ++- 4 files changed, 107 insertions(+), 54 deletions(-) create mode 100644 packages/website/src/components/constants.ts diff --git a/packages/eslint-plugin/docs/rules/README.md b/packages/eslint-plugin/docs/rules/README.md index 71da9b1fd153..7240c6a279f3 100644 --- a/packages/eslint-plugin/docs/rules/README.md +++ b/packages/eslint-plugin/docs/rules/README.md @@ -6,18 +6,25 @@ pagination_prev: null slug: / --- -`@typescript-eslint/eslint-plugin` includes over 100 rules that detect best practice violations, bugs, and/or stylistic issues specifically for TypeScript code. -See [Configs](/linting/configs) for how to enable recommended rules using configs. +## Introduction -## Supported Rules +`@typescript-eslint/eslint-plugin` includes over 100 rules that detect best practice violations, bugs, and/or stylistic issues specifically for TypeScript code. All of our rules are listed below. -import RulesTable from "@site/src/components/RulesTable"; +Instead of enabling rules one by one, we recommend using one of [our pre-defined configs](/linting/configs) to easily enable a large set of +recommended rules. + +## Sorting - +The rules are listed in alphabetical order, but you can sort them based on a few categories: -## Extension Rules +- "Config Group" refers to the configuration preset. We offer [three different config groups](/linting/configs) that allow users to enable a large set of recommended rules all at once. +- `🔧 fixable` refers to whether the rule contains an ESLint auto-fixer. If the rule has an auto-fixer, then some rule violations can be fixed by running `eslint` with the `--fix` flag. This will automatically change the code, which can save a lot of time! (It is a common pattern for developers to configure their IDE to automatically run `eslint --fix` when saving a TypeScript file.) +- `💡 has suggestions` refers to whether the rule will offer a suggestion of how to fix the code. Sometimes, it is not safe to automatically fix the code with an auto-fixer. But in these cases, we often have a good guess of what the correct fix should be, and we can provide it as a suggestion to the developer. +- `💭 requires type information` refers to whether the rule needs to leverage the power of the TypeScript compiler in order to work properly. Rules that require type information are usually much slower than rules that don't. Thus, if linting performance becomes an issue in a gigantic codebase, a good first step might be make rules that require type information run only in CI. +- `🧱 extension rule` means that the rule was originally a [core ESLint rule](https://eslint.org/docs/latest/rules/). Some core ESLint rules do not support TypeScript syntax: either they crash, ignore the syntax, or falsely report against it. In these cases, we create an "extension rule": a rule within our plugin that has the same functionality, but also supports TypeScript. -In some cases, ESLint provides a rule itself, but it doesn't support TypeScript syntax; either it crashes, or it ignores the syntax, or it falsely reports against it. -In these cases, we create what we call an extension rule; a rule within our plugin that has the same functionality, but also supports TypeScript. +## Rules + +import RulesTable from "@site/src/components/RulesTable"; - + diff --git a/packages/website/src/components/RulesTable/index.tsx b/packages/website/src/components/RulesTable/index.tsx index f1270d34b73c..270be5608aec 100644 --- a/packages/website/src/components/RulesTable/index.tsx +++ b/packages/website/src/components/RulesTable/index.tsx @@ -9,6 +9,15 @@ import { type HistorySelector, useHistorySelector, } from '../../hooks/useHistorySelector'; +import { + EXTENSION_RULE_EMOJI, + FIXABLE_EMOJI, + RECOMMENDED_CONFIG_EMOJI, + STRICT_CONFIG_EMOJI, + STYLISTIC_CONFIG_EMOJI, + SUGGESTIONS_EMOJI, + TYPE_INFORMATION_EMOJI, +} from '../constants'; import styles from './styles.module.css'; function interpolateCode( @@ -30,7 +39,7 @@ function RuleRow({ return null; } const { fixable, hasSuggestions } = rule; - const { recommended, requiresTypeChecking } = rule.docs; + const { recommended, requiresTypeChecking, extendsBaseRule } = rule.docs; return ( @@ -44,11 +53,11 @@ function RuleRow({ {(() => { switch (recommended) { case 'recommended': - return '✅'; + return RECOMMENDED_CONFIG_EMOJI; case 'strict': - return '🔒'; + return STRICT_CONFIG_EMOJI; case 'stylistic': - return '🎨'; + return STYLISTIC_CONFIG_EMOJI; default: // for some reason the current version of babel loader won't elide this correctly // recommended satisfies undefined; @@ -68,14 +77,20 @@ function RuleRow({ : undefined } > - {fixable ? '🔧\n' : '\n'} - {hasSuggestions ? '💡' : ''} + {fixable ? `${FIXABLE_EMOJI}\n` : '\n'} + {hasSuggestions ? SUGGESTIONS_EMOJI : ''} - {requiresTypeChecking ? '💭' : ''} + {requiresTypeChecking ? TYPE_INFORMATION_EMOJI : ''} + + + {extendsBaseRule ? EXTENSION_RULE_EMOJI : ''} ); @@ -132,35 +147,29 @@ function match(mode: FilterMode, value: boolean): boolean | undefined { return undefined; } -export default function RulesTable({ - ruleset, -}: { - ruleset: 'extension-rules' | 'supported-rules'; -}): React.JSX.Element { - const [filters, changeFilter] = useRulesFilters(ruleset); +export default function RulesTable(): React.JSX.Element { + const [filters, changeFilter] = useRulesFilters(); const rules = useRulesMeta(); - const extensionRules = ruleset === 'extension-rules'; const relevantRules = useMemo( () => - rules - .filter(r => !!extensionRules === !!r.docs?.extendsBaseRule) - .filter(r => { - const opinions = [ - match(filters.recommended, r.docs?.recommended === 'recommended'), - match( - filters.strict, - r.docs?.recommended === 'recommended' || - r.docs?.recommended === 'strict', - ), - match(filters.stylistic, r.docs?.recommended === 'stylistic'), - match(filters.fixable, !!r.fixable), - match(filters.suggestions, !!r.hasSuggestions), - match(filters.typeInformation, !!r.docs?.requiresTypeChecking), - ].filter((o): o is boolean => o !== undefined); - return opinions.every(o => o); - }), - [rules, extensionRules, filters], + rules.filter(r => { + const opinions = [ + match(filters.recommended, r.docs?.recommended === 'recommended'), + match( + filters.strict, + r.docs?.recommended === 'recommended' || + r.docs?.recommended === 'strict', + ), + match(filters.stylistic, r.docs?.recommended === 'stylistic'), + match(filters.fixable, !!r.fixable), + match(filters.suggestions, !!r.hasSuggestions), + match(filters.typeInformation, !!r.docs?.requiresTypeChecking), + match(filters.extension, !!r.docs?.extendsBaseRule), + ].filter((o): o is boolean => o !== undefined); + return opinions.every(o => o); + }), + [rules, filters], ); return ( @@ -171,17 +180,17 @@ export default function RulesTable({ changeFilter('recommended', newMode)} - label="✅ recommended" + label={`${RECOMMENDED_CONFIG_EMOJI} recommended`} /> changeFilter('strict', newMode)} - label="🔒 strict" + label={`${STRICT_CONFIG_EMOJI} strict`} /> changeFilter('stylistic', newMode)} - label="🎨 stylistic" + label={`${STYLISTIC_CONFIG_EMOJI} stylistic`} /> @@ -191,19 +200,24 @@ export default function RulesTable({ changeFilter('fixable', newMode)} - label="🔧 fixable" + label={`${FIXABLE_EMOJI} fixable`} /> changeFilter('suggestions', newMode)} - label="💡 has suggestions" + label={`${SUGGESTIONS_EMOJI} has suggestions`} /> changeFilter('typeInformation', newMode) } - label="💭 requires type information" + label={`${TYPE_INFORMATION_EMOJI} requires type information`} + /> + changeFilter('extension', newMode)} + label={`${EXTENSION_RULE_EMOJI} extension rule`} /> @@ -214,6 +228,7 @@ export default function RulesTable({ Config Fixer Typed + Extension @@ -232,7 +247,8 @@ type FilterCategory = | 'strict' | 'stylistic' | 'suggestions' - | 'typeInformation'; + | 'typeInformation' + | 'extension'; type FiltersState = Record; const neutralFiltersState: FiltersState = { recommended: 'neutral', @@ -241,14 +257,19 @@ const neutralFiltersState: FiltersState = { fixable: 'neutral', suggestions: 'neutral', typeInformation: 'neutral', + extension: 'neutral', }; const selectSearch: HistorySelector = history => history.location.search; const getServerSnapshot = (): string => ''; +/** + * @param paramsKey Optional. Whether to include rules that match the particular + * search filter. Defaults to an empty string, which matches all rules. + */ function useRulesFilters( - paramsKey: string, + paramsKey = '', ): [FiltersState, (category: FilterCategory, mode: FilterMode) => void] { const history = useHistory(); const search = useHistorySelector(selectSearch, getServerSnapshot); diff --git a/packages/website/src/components/constants.ts b/packages/website/src/components/constants.ts new file mode 100644 index 000000000000..27119347f53b --- /dev/null +++ b/packages/website/src/components/constants.ts @@ -0,0 +1,18 @@ +export const RECOMMENDED_CONFIG_EMOJI = '✅'; +export const STRICT_CONFIG_EMOJI = '🔒'; +export const STYLISTIC_CONFIG_EMOJI = '🎨'; + +export const FIXABLE_EMOJI = '🔧'; +export const SUGGESTIONS_EMOJI = '💡'; + +/** + * This must be kept in sync with the emoji in the + * "generate-breaking-changes.mts" script. + */ +export const TYPE_INFORMATION_EMOJI = '💭'; + +/** + * This must be kept in sync with the emoji in the + * "generate-breaking-changes.mts" script. + */ +export const EXTENSION_RULE_EMOJI = '🧱'; diff --git a/packages/website/src/theme/MDXComponents/RuleAttributes.tsx b/packages/website/src/theme/MDXComponents/RuleAttributes.tsx index 9094d8a980fc..365dd15b1e8d 100644 --- a/packages/website/src/theme/MDXComponents/RuleAttributes.tsx +++ b/packages/website/src/theme/MDXComponents/RuleAttributes.tsx @@ -3,14 +3,21 @@ import type { RuleMetaDataDocs } from '@site/../utils/dist/ts-eslint/Rule'; import { useRulesMeta } from '@site/src/hooks/useRulesMeta'; import React from 'react'; +import { + FIXABLE_EMOJI, + RECOMMENDED_CONFIG_EMOJI, + STRICT_CONFIG_EMOJI, + STYLISTIC_CONFIG_EMOJI, + SUGGESTIONS_EMOJI, +} from '../../components/constants'; import type { FeatureProps } from './Feature'; import { Feature } from './Feature'; import styles from './RuleAttributes.module.css'; const recommendations = { - recommended: ['✅', 'recommended'], - strict: ['🔒', 'strict'], - stylistic: ['🎨', 'stylistic'], + recommended: [RECOMMENDED_CONFIG_EMOJI, 'recommended'], + strict: [STRICT_CONFIG_EMOJI, 'strict'], + stylistic: [STYLISTIC_CONFIG_EMOJI, 'stylistic'], }; const getRecommendation = (docs: RuleMetaDataDocs): string[] => { @@ -63,7 +70,7 @@ export function RuleAttributes({ name }: { name: string }): React.ReactNode { . ), - emoji: '🔧', + emoji: FIXABLE_EMOJI, }); } @@ -78,7 +85,7 @@ export function RuleAttributes({ name }: { name: string }): React.ReactNode { . ), - emoji: '💡', + emoji: SUGGESTIONS_EMOJI, }); } From 23cf04b2742c674773e425c64951cbb2a0c2a49d Mon Sep 17 00:00:00 2001 From: James <5511220+Zamiell@users.noreply.github.com> Date: Sun, 17 Sep 2023 12:49:26 -0400 Subject: [PATCH 02/19] docs: make sorting columns smaller --- packages/eslint-plugin/docs/rules/README.md | 2 + .../eslint-plugin/docs/rules/camelcase.md | 7 ++- .../docs/rules/no-duplicate-imports.md | 7 ++- packages/eslint-plugin/tests/docs.test.ts | 3 +- .../tools/generate-breaking-changes.mts | 2 +- packages/website/sidebars/sidebar.rules.js | 51 +--------------- .../src/components/RulesTable/index.tsx | 61 ++++++++++++++++--- packages/website/src/components/constants.ts | 12 ++++ 8 files changed, 81 insertions(+), 64 deletions(-) diff --git a/packages/eslint-plugin/docs/rules/README.md b/packages/eslint-plugin/docs/rules/README.md index 7240c6a279f3..4cf5649a87ac 100644 --- a/packages/eslint-plugin/docs/rules/README.md +++ b/packages/eslint-plugin/docs/rules/README.md @@ -22,6 +22,8 @@ The rules are listed in alphabetical order, but you can sort them based on a few - `💡 has suggestions` refers to whether the rule will offer a suggestion of how to fix the code. Sometimes, it is not safe to automatically fix the code with an auto-fixer. But in these cases, we often have a good guess of what the correct fix should be, and we can provide it as a suggestion to the developer. - `💭 requires type information` refers to whether the rule needs to leverage the power of the TypeScript compiler in order to work properly. Rules that require type information are usually much slower than rules that don't. Thus, if linting performance becomes an issue in a gigantic codebase, a good first step might be make rules that require type information run only in CI. - `🧱 extension rule` means that the rule was originally a [core ESLint rule](https://eslint.org/docs/latest/rules/). Some core ESLint rules do not support TypeScript syntax: either they crash, ignore the syntax, or falsely report against it. In these cases, we create an "extension rule": a rule within our plugin that has the same functionality, but also supports TypeScript. +- `📐 formatting rule` means that the rule has to do with formatting. Formatting rules are mostly here for legacy purposes, because we [strongly recommend against using ESLint for formatting](/linting/troubleshooting/formatting). +- `💀 deprecated rule` means that the rule should no longer be used and will be removed from the plugin in a future version. ## Rules diff --git a/packages/eslint-plugin/docs/rules/camelcase.md b/packages/eslint-plugin/docs/rules/camelcase.md index aae38de928bb..2a85ab90c5e4 100644 --- a/packages/eslint-plugin/docs/rules/camelcase.md +++ b/packages/eslint-plugin/docs/rules/camelcase.md @@ -5,6 +5,9 @@ This rule has been deprecated in favour of the [`naming-convention`](./naming-co ::: diff --git a/packages/eslint-plugin/docs/rules/no-duplicate-imports.md b/packages/eslint-plugin/docs/rules/no-duplicate-imports.md index 9bf40498092f..ae1d957d57c0 100644 --- a/packages/eslint-plugin/docs/rules/no-duplicate-imports.md +++ b/packages/eslint-plugin/docs/rules/no-duplicate-imports.md @@ -5,6 +5,9 @@ This rule has been deprecated in favour of the [`import/no-duplicates`](https:// ::: diff --git a/packages/eslint-plugin/tests/docs.test.ts b/packages/eslint-plugin/tests/docs.test.ts index a2bef8cac839..ce9f3115a02f 100644 --- a/packages/eslint-plugin/tests/docs.test.ts +++ b/packages/eslint-plugin/tests/docs.test.ts @@ -42,7 +42,8 @@ describe('Validating rule docs', () => { const ignoredFiles = new Set([ 'README.md', 'TEMPLATE.md', - // these rule docs were left behind on purpose for legacy reasons + // These rule docs were left behind on purpose for legacy reasons. See the + // comments in the files for more information. 'camelcase.md', 'no-duplicate-imports.md', ]); diff --git a/packages/eslint-plugin/tools/generate-breaking-changes.mts b/packages/eslint-plugin/tools/generate-breaking-changes.mts index d4ec9233e6c3..05f4d8d5485a 100644 --- a/packages/eslint-plugin/tools/generate-breaking-changes.mts +++ b/packages/eslint-plugin/tools/generate-breaking-changes.mts @@ -141,7 +141,7 @@ async function main(): Promise { recommended === 'recommended' ? '🟩' : '', recommended === 'strict' ? '🔵' : '', recommended === 'stylistic' ? '🔸' : '', - meta.type === 'layout' ? 'layout 💩' : '(todo)', + meta.type === 'layout' ? 'layout 📐' : '(todo)', ]; }), ]), diff --git a/packages/website/sidebars/sidebar.rules.js b/packages/website/sidebars/sidebar.rules.js index e698d7cda05c..4e6887df8cd9 100644 --- a/packages/website/sidebars/sidebar.rules.js +++ b/packages/website/sidebars/sidebar.rules.js @@ -1,6 +1,3 @@ -const globby = require('globby'); -const path = require('path'); - const plugin = require('@typescript-eslint/eslint-plugin'); const rules = Object.entries(plugin.rules).map(([name, rule]) => { @@ -10,43 +7,6 @@ const rules = Object.entries(plugin.rules).map(([name, rule]) => { }; }); -const deprecatedRules = new Set(rules.filter(rule => rule.meta.deprecated)); - -const formattingRules = new Set( - rules.filter(rule => !rule.meta.deprecated && rule.meta.type === 'layout'), -); - -const extensionRules = new Set( - rules.filter( - rule => rule.meta.docs?.extendsBaseRule && !formattingRules.has(rule), - ), -); - -const typescriptRules = rules.filter( - rule => - !rule.meta.deprecated && - !extensionRules.has(rule) && - !deprecatedRules.has(rule) && - !formattingRules.has(rule), -); - -const paths = globby - .sync('*.md', { - cwd: path.join(__dirname, '../../eslint-plugin/docs/rules'), - }) - .map(item => { - return { - name: path.basename(item, '.md'), - }; - }) - .filter(item => { - return ( - item.name !== 'README' && - item.name !== 'TEMPLATE' && - !rules.some(a => a.name === item.name) - ); - }); - function createCategory(label, rules, additionalItems = []) { return { items: [ @@ -68,17 +28,8 @@ module.exports = { someSidebar: [ 'README', { - ...createCategory('TypeScript Rules', Array.from(typescriptRules)), - collapsed: false, - }, - { - ...createCategory('Extension Rules', Array.from(extensionRules)), + ...createCategory('Rules', rules), collapsed: false, }, - createCategory('Formatting Rules', Array.from(formattingRules)), - createCategory('Deprecated Rules', [ - ...Array.from(deprecatedRules), - ...paths, - ]), ], }; diff --git a/packages/website/src/components/RulesTable/index.tsx b/packages/website/src/components/RulesTable/index.tsx index 270be5608aec..a19416f76572 100644 --- a/packages/website/src/components/RulesTable/index.tsx +++ b/packages/website/src/components/RulesTable/index.tsx @@ -10,8 +10,10 @@ import { useHistorySelector, } from '../../hooks/useHistorySelector'; import { + DEPRECATED_RULE_EMOJI, EXTENSION_RULE_EMOJI, FIXABLE_EMOJI, + FORMATTING_RULE_EMOJI, RECOMMENDED_CONFIG_EMOJI, STRICT_CONFIG_EMOJI, STYLISTIC_CONFIG_EMOJI, @@ -38,8 +40,9 @@ function RuleRow({ if (!rule.docs?.url) { return null; } - const { fixable, hasSuggestions } = rule; + const { fixable, hasSuggestions, type, deprecated } = rule; const { recommended, requiresTypeChecking, extendsBaseRule } = rule.docs; + const formatting = type === "layout"; return ( @@ -59,8 +62,8 @@ function RuleRow({ case 'stylistic': return STYLISTIC_CONFIG_EMOJI; default: - // for some reason the current version of babel loader won't elide this correctly - // recommended satisfies undefined; + // for some reason the current version of babel loader won't elide + // this correctly recommended satisfies undefined; return ''; } })()} @@ -92,6 +95,18 @@ function RuleRow({ > {extendsBaseRule ? EXTENSION_RULE_EMOJI : ''} + + {formatting ? FORMATTING_RULE_EMOJI : ''} + + + {deprecated ? DEPRECATED_RULE_EMOJI : ''} + ); } @@ -166,6 +181,8 @@ export default function RulesTable(): React.JSX.Element { match(filters.suggestions, !!r.hasSuggestions), match(filters.typeInformation, !!r.docs?.requiresTypeChecking), match(filters.extension, !!r.docs?.extendsBaseRule), + match(filters.formatting, r.type === 'layout'), + match(filters.deprecated, !!r.deprecated), ].filter((o): o is boolean => o !== undefined); return opinions.every(o => o); }), @@ -219,16 +236,40 @@ export default function RulesTable(): React.JSX.Element { setMode={(newMode): void => changeFilter('extension', newMode)} label={`${EXTENSION_RULE_EMOJI} extension rule`} /> + changeFilter('formatting', newMode)} + label={`${FORMATTING_RULE_EMOJI} formatting rule`} + /> + changeFilter('deprecated', newMode)} + label={`${DEPRECATED_RULE_EMOJI} deprecated rule`} + /> - - - - + + + + + + @@ -248,7 +289,9 @@ type FilterCategory = | 'stylistic' | 'suggestions' | 'typeInformation' - | 'extension'; + | 'extension' + | 'formatting' + | 'deprecated'; type FiltersState = Record; const neutralFiltersState: FiltersState = { recommended: 'neutral', @@ -258,6 +301,8 @@ const neutralFiltersState: FiltersState = { suggestions: 'neutral', typeInformation: 'neutral', extension: 'neutral', + formatting: 'neutral', + deprecated: 'neutral', }; const selectSearch: HistorySelector = history => diff --git a/packages/website/src/components/constants.ts b/packages/website/src/components/constants.ts index 27119347f53b..82bdba24715b 100644 --- a/packages/website/src/components/constants.ts +++ b/packages/website/src/components/constants.ts @@ -16,3 +16,15 @@ export const TYPE_INFORMATION_EMOJI = '💭'; * "generate-breaking-changes.mts" script. */ export const EXTENSION_RULE_EMOJI = '🧱'; + +/** + * This must be kept in sync with the emoji in the + * "generate-breaking-changes.mts" script. + */ +export const FORMATTING_RULE_EMOJI = '📐'; + +/** + * This must be kept in sync with the emoji in the + * "generate-breaking-changes.mts" script. + */ +export const DEPRECATED_RULE_EMOJI = '💀'; From 37d5f1f71fbb577a0539d57964c391f88af7f6b7 Mon Sep 17 00:00:00 2001 From: James <5511220+Zamiell@users.noreply.github.com> Date: Sun, 17 Sep 2023 13:23:40 -0400 Subject: [PATCH 03/19] fix: prettier --- .../src/components/RulesTable/index.tsx | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/packages/website/src/components/RulesTable/index.tsx b/packages/website/src/components/RulesTable/index.tsx index a19416f76572..1fda0979e4b5 100644 --- a/packages/website/src/components/RulesTable/index.tsx +++ b/packages/website/src/components/RulesTable/index.tsx @@ -42,7 +42,7 @@ function RuleRow({ } const { fixable, hasSuggestions, type, deprecated } = rule; const { recommended, requiresTypeChecking, extendsBaseRule } = rule.docs; - const formatting = type === "layout"; + const formatting = type === 'layout'; return (
RuleConfigFixerTypedExtension + + + + + + + + + + + +
@@ -253,19 +253,29 @@ export default function RulesTable(): React.JSX.Element {
Rule - + - + - + - + - + From 2259ef8054acd7e77a4ece535bc7aaa6754cdaa1 Mon Sep 17 00:00:00 2001 From: James <5511220+Zamiell@users.noreply.github.com> Date: Mon, 18 Sep 2023 11:36:17 -0400 Subject: [PATCH 04/19] fix: metadata on 1 line --- packages/website/src/components/RulesTable/index.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/website/src/components/RulesTable/index.tsx b/packages/website/src/components/RulesTable/index.tsx index 1fda0979e4b5..120607c43758 100644 --- a/packages/website/src/components/RulesTable/index.tsx +++ b/packages/website/src/components/RulesTable/index.tsx @@ -234,17 +234,17 @@ export default function RulesTable(): React.JSX.Element { changeFilter('extension', newMode)} - label={`${EXTENSION_RULE_EMOJI} extension rule`} + label={`${EXTENSION_RULE_EMOJI} extension`} /> changeFilter('formatting', newMode)} - label={`${FORMATTING_RULE_EMOJI} formatting rule`} + label={`${FORMATTING_RULE_EMOJI} formatting`} /> changeFilter('deprecated', newMode)} - label={`${DEPRECATED_RULE_EMOJI} deprecated rule`} + label={`${DEPRECATED_RULE_EMOJI} deprecated`} /> From bd14e9afd9907c962b2a48dcf104cf3cf5ea50d2 Mon Sep 17 00:00:00 2001 From: James <5511220+Zamiell@users.noreply.github.com> Date: Mon, 18 Sep 2023 11:46:40 -0400 Subject: [PATCH 05/19] fix: sort description at bottom --- packages/eslint-plugin/docs/rules/README.md | 16 ++++++++-------- .../website/src/components/RulesTable/index.tsx | 4 ++++ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/eslint-plugin/docs/rules/README.md b/packages/eslint-plugin/docs/rules/README.md index 4cf5649a87ac..5b63f63d0a18 100644 --- a/packages/eslint-plugin/docs/rules/README.md +++ b/packages/eslint-plugin/docs/rules/README.md @@ -13,9 +13,15 @@ slug: / Instead of enabling rules one by one, we recommend using one of [our pre-defined configs](/linting/configs) to easily enable a large set of recommended rules. -## Sorting +## Rules + +The rules are listed in alphabetical order. You can optionally sort them based on these categories: + +import RulesTable from "@site/src/components/RulesTable"; + + -The rules are listed in alphabetical order, but you can sort them based on a few categories: +## Sorting - "Config Group" refers to the configuration preset. We offer [three different config groups](/linting/configs) that allow users to enable a large set of recommended rules all at once. - `🔧 fixable` refers to whether the rule contains an ESLint auto-fixer. If the rule has an auto-fixer, then some rule violations can be fixed by running `eslint` with the `--fix` flag. This will automatically change the code, which can save a lot of time! (It is a common pattern for developers to configure their IDE to automatically run `eslint --fix` when saving a TypeScript file.) @@ -24,9 +30,3 @@ The rules are listed in alphabetical order, but you can sort them based on a few - `🧱 extension rule` means that the rule was originally a [core ESLint rule](https://eslint.org/docs/latest/rules/). Some core ESLint rules do not support TypeScript syntax: either they crash, ignore the syntax, or falsely report against it. In these cases, we create an "extension rule": a rule within our plugin that has the same functionality, but also supports TypeScript. - `📐 formatting rule` means that the rule has to do with formatting. Formatting rules are mostly here for legacy purposes, because we [strongly recommend against using ESLint for formatting](/linting/troubleshooting/formatting). - `💀 deprecated rule` means that the rule should no longer be used and will be removed from the plugin in a future version. - -## Rules - -import RulesTable from "@site/src/components/RulesTable"; - - diff --git a/packages/website/src/components/RulesTable/index.tsx b/packages/website/src/components/RulesTable/index.tsx index 120607c43758..7689e07938ab 100644 --- a/packages/website/src/components/RulesTable/index.tsx +++ b/packages/website/src/components/RulesTable/index.tsx @@ -248,6 +248,10 @@ export default function RulesTable(): React.JSX.Element { /> +

+ (These categories are explained in{' '} + more detail below.) +

From 58f370b727ebdbd15bc350e2abf39f595722a2f8 Mon Sep 17 00:00:00 2001 From: James <5511220+Zamiell@users.noreply.github.com> Date: Mon, 18 Sep 2023 13:57:13 -0400 Subject: [PATCH 06/19] fix: remove buttons --- .../src/components/RulesTable/index.tsx | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/packages/website/src/components/RulesTable/index.tsx b/packages/website/src/components/RulesTable/index.tsx index 7689e07938ab..e377c68aae81 100644 --- a/packages/website/src/components/RulesTable/index.tsx +++ b/packages/website/src/components/RulesTable/index.tsx @@ -257,32 +257,34 @@ export default function RulesTable(): React.JSX.Element { From 23bcddb660f43d1bf1351b6e4ce5623604433097 Mon Sep 17 00:00:00 2001 From: James <5511220+Zamiell@users.noreply.github.com> Date: Sat, 23 Sep 2023 00:25:21 -0400 Subject: [PATCH 07/19] Update README.md --- packages/eslint-plugin/docs/rules/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/eslint-plugin/docs/rules/README.md b/packages/eslint-plugin/docs/rules/README.md index 5b63f63d0a18..12843eb64c48 100644 --- a/packages/eslint-plugin/docs/rules/README.md +++ b/packages/eslint-plugin/docs/rules/README.md @@ -6,8 +6,6 @@ pagination_prev: null slug: / --- -## Introduction - `@typescript-eslint/eslint-plugin` includes over 100 rules that detect best practice violations, bugs, and/or stylistic issues specifically for TypeScript code. All of our rules are listed below. Instead of enabling rules one by one, we recommend using one of [our pre-defined configs](/linting/configs) to easily enable a large set of From 37f13fc04047170b3343c6744770f32827684420 Mon Sep 17 00:00:00 2001 From: James <5511220+Zamiell@users.noreply.github.com> Date: Fri, 13 Oct 2023 15:10:53 -0400 Subject: [PATCH 08/19] Update packages/eslint-plugin/docs/rules/README.md Co-authored-by: Joshua Chen --- packages/eslint-plugin/docs/rules/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/eslint-plugin/docs/rules/README.md b/packages/eslint-plugin/docs/rules/README.md index 12843eb64c48..aef6317b733b 100644 --- a/packages/eslint-plugin/docs/rules/README.md +++ b/packages/eslint-plugin/docs/rules/README.md @@ -8,8 +8,7 @@ slug: / `@typescript-eslint/eslint-plugin` includes over 100 rules that detect best practice violations, bugs, and/or stylistic issues specifically for TypeScript code. All of our rules are listed below. -Instead of enabling rules one by one, we recommend using one of [our pre-defined configs](/linting/configs) to easily enable a large set of -recommended rules. +Instead of enabling rules one by one, we recommend using one of [our pre-defined configs](/linting/configs) to easily enable a large set of recommended rules. ## Rules From d23a3f87ac9673b4e6b638571e32c913c05aaeab Mon Sep 17 00:00:00 2001 From: James <5511220+Zamiell@users.noreply.github.com> Date: Fri, 13 Oct 2023 15:13:29 -0400 Subject: [PATCH 09/19] Update packages/website/src/components/RulesTable/index.tsx Co-authored-by: Joshua Chen --- packages/website/src/components/RulesTable/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/website/src/components/RulesTable/index.tsx b/packages/website/src/components/RulesTable/index.tsx index e377c68aae81..4801efd8108b 100644 --- a/packages/website/src/components/RulesTable/index.tsx +++ b/packages/website/src/components/RulesTable/index.tsx @@ -80,7 +80,7 @@ function RuleRow({ : undefined } > - {fixable ? `${FIXABLE_EMOJI}\n` : '\n'} + {fixable ? FIXABLE_EMOJI : ''}
{hasSuggestions ? SUGGESTIONS_EMOJI : ''}
Rule - +
+ ⚙️ {/* We use a gear to represent "Config". */} +
- +
+ {FIXABLE_EMOJI} +
- +
+ {TYPE_INFORMATION_EMOJI} +
- +
+ {EXTENSION_RULE_EMOJI} +
- +
+ {FORMATTING_RULE_EMOJI} +
- +
+ {DEPRECATED_RULE_EMOJI} +
Date: Fri, 13 Oct 2023 15:16:28 -0400 Subject: [PATCH 10/19] fix: sort --> filter --- packages/eslint-plugin/docs/rules/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/eslint-plugin/docs/rules/README.md b/packages/eslint-plugin/docs/rules/README.md index aef6317b733b..15a66b6b6c57 100644 --- a/packages/eslint-plugin/docs/rules/README.md +++ b/packages/eslint-plugin/docs/rules/README.md @@ -12,13 +12,13 @@ Instead of enabling rules one by one, we recommend using one of [our pre-defined ## Rules -The rules are listed in alphabetical order. You can optionally sort them based on these categories: +The rules are listed in alphabetical order. You can optionally filter them based on these categories: import RulesTable from "@site/src/components/RulesTable"; -## Sorting +## Filtering - "Config Group" refers to the configuration preset. We offer [three different config groups](/linting/configs) that allow users to enable a large set of recommended rules all at once. - `🔧 fixable` refers to whether the rule contains an ESLint auto-fixer. If the rule has an auto-fixer, then some rule violations can be fixed by running `eslint` with the `--fix` flag. This will automatically change the code, which can save a lot of time! (It is a common pattern for developers to configure their IDE to automatically run `eslint --fix` when saving a TypeScript file.) From fefe2eb316caf8aaff72f680a04f30233674e2de Mon Sep 17 00:00:00 2001 From: James <5511220+Zamiell@users.noreply.github.com> Date: Fri, 13 Oct 2023 15:17:15 -0400 Subject: [PATCH 11/19] fix: sort --> filter --- packages/website/src/components/RulesTable/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/website/src/components/RulesTable/index.tsx b/packages/website/src/components/RulesTable/index.tsx index 4801efd8108b..0dc92fc86346 100644 --- a/packages/website/src/components/RulesTable/index.tsx +++ b/packages/website/src/components/RulesTable/index.tsx @@ -250,7 +250,7 @@ export default function RulesTable(): React.JSX.Element {

(These categories are explained in{' '} - more detail below.) + more detail below.)

From 868ea0b6cbb27925ef342101c0fffa59c741ed50 Mon Sep 17 00:00:00 2001 From: James <5511220+Zamiell@users.noreply.github.com> Date: Sun, 15 Oct 2023 15:10:29 -0400 Subject: [PATCH 12/19] Update packages/eslint-plugin/docs/rules/README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Josh Goldberg ✨ --- packages/eslint-plugin/docs/rules/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-plugin/docs/rules/README.md b/packages/eslint-plugin/docs/rules/README.md index 15a66b6b6c57..cace722dfa36 100644 --- a/packages/eslint-plugin/docs/rules/README.md +++ b/packages/eslint-plugin/docs/rules/README.md @@ -8,7 +8,7 @@ slug: / `@typescript-eslint/eslint-plugin` includes over 100 rules that detect best practice violations, bugs, and/or stylistic issues specifically for TypeScript code. All of our rules are listed below. -Instead of enabling rules one by one, we recommend using one of [our pre-defined configs](/linting/configs) to easily enable a large set of recommended rules. +Instead of enabling rules one by one, we recommend using one of [our pre-defined configs](/linting/configs) to enable a large set of recommended rules. ## Rules From a3457e3a848951dac105979bf43fc74fae15d47d Mon Sep 17 00:00:00 2001 From: James <5511220+Zamiell@users.noreply.github.com> Date: Sun, 15 Oct 2023 15:15:40 -0400 Subject: [PATCH 13/19] feat: adding tip --- packages/eslint-plugin/docs/rules/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/eslint-plugin/docs/rules/README.md b/packages/eslint-plugin/docs/rules/README.md index cace722dfa36..37ec61bfa936 100644 --- a/packages/eslint-plugin/docs/rules/README.md +++ b/packages/eslint-plugin/docs/rules/README.md @@ -8,7 +8,9 @@ slug: / `@typescript-eslint/eslint-plugin` includes over 100 rules that detect best practice violations, bugs, and/or stylistic issues specifically for TypeScript code. All of our rules are listed below. +:::tip Instead of enabling rules one by one, we recommend using one of [our pre-defined configs](/linting/configs) to enable a large set of recommended rules. +::: ## Rules From ca9e428ce43c3981a0b2a9062beaec4d5236f8f5 Mon Sep 17 00:00:00 2001 From: James <5511220+Zamiell@users.noreply.github.com> Date: Sun, 15 Oct 2023 15:17:34 -0400 Subject: [PATCH 14/19] feat: config emoji --- packages/website/src/components/RulesTable/index.tsx | 5 +++-- packages/website/src/components/constants.ts | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/website/src/components/RulesTable/index.tsx b/packages/website/src/components/RulesTable/index.tsx index 0dc92fc86346..f15bdcfe79bc 100644 --- a/packages/website/src/components/RulesTable/index.tsx +++ b/packages/website/src/components/RulesTable/index.tsx @@ -10,6 +10,7 @@ import { useHistorySelector, } from '../../hooks/useHistorySelector'; import { + CONFIG_EMOJI, DEPRECATED_RULE_EMOJI, EXTENSION_RULE_EMOJI, FIXABLE_EMOJI, @@ -192,7 +193,7 @@ export default function RulesTable(): React.JSX.Element { return ( <>
- Config Group + Config Group ({CONFIG_EMOJI})
    Rule
- ⚙️ {/* We use a gear to represent "Config". */} + {CONFIG_EMOJI}
diff --git a/packages/website/src/components/constants.ts b/packages/website/src/components/constants.ts index 82bdba24715b..ec55bfa14585 100644 --- a/packages/website/src/components/constants.ts +++ b/packages/website/src/components/constants.ts @@ -1,3 +1,5 @@ +export const CONFIG_EMOJI = '⚙️'; + export const RECOMMENDED_CONFIG_EMOJI = '✅'; export const STRICT_CONFIG_EMOJI = '🔒'; export const STYLISTIC_CONFIG_EMOJI = '🎨'; From e643ed523048573b3e3f9d96f3c60f3baf0f69bd Mon Sep 17 00:00:00 2001 From: James <5511220+Zamiell@users.noreply.github.com> Date: Sun, 15 Oct 2023 15:21:12 -0400 Subject: [PATCH 15/19] feat: shorten filtering docs --- packages/eslint-plugin/docs/rules/README.md | 22 +++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/packages/eslint-plugin/docs/rules/README.md b/packages/eslint-plugin/docs/rules/README.md index 37ec61bfa936..01ea7f19f849 100644 --- a/packages/eslint-plugin/docs/rules/README.md +++ b/packages/eslint-plugin/docs/rules/README.md @@ -22,10 +22,20 @@ import RulesTable from "@site/src/components/RulesTable"; ## Filtering -- "Config Group" refers to the configuration preset. We offer [three different config groups](/linting/configs) that allow users to enable a large set of recommended rules all at once. -- `🔧 fixable` refers to whether the rule contains an ESLint auto-fixer. If the rule has an auto-fixer, then some rule violations can be fixed by running `eslint` with the `--fix` flag. This will automatically change the code, which can save a lot of time! (It is a common pattern for developers to configure their IDE to automatically run `eslint --fix` when saving a TypeScript file.) -- `💡 has suggestions` refers to whether the rule will offer a suggestion of how to fix the code. Sometimes, it is not safe to automatically fix the code with an auto-fixer. But in these cases, we often have a good guess of what the correct fix should be, and we can provide it as a suggestion to the developer. -- `💭 requires type information` refers to whether the rule needs to leverage the power of the TypeScript compiler in order to work properly. Rules that require type information are usually much slower than rules that don't. Thus, if linting performance becomes an issue in a gigantic codebase, a good first step might be make rules that require type information run only in CI. -- `🧱 extension rule` means that the rule was originally a [core ESLint rule](https://eslint.org/docs/latest/rules/). Some core ESLint rules do not support TypeScript syntax: either they crash, ignore the syntax, or falsely report against it. In these cases, we create an "extension rule": a rule within our plugin that has the same functionality, but also supports TypeScript. -- `📐 formatting rule` means that the rule has to do with formatting. Formatting rules are mostly here for legacy purposes, because we [strongly recommend against using ESLint for formatting](/linting/troubleshooting/formatting). +### Config Group (⚙️) + +"Config Group" refers to the [pre-defined config](/linting/configs) that includes the rule. Extending from a configuration preset allow for enabling a large set of recommended rules all at once. + +### Metadata + +- `🔧 fixable` refers to whether the rule contains an [ESLint `--fix` auto-fixer](https://eslint.org/docs/latest/use/command-line-interface#--fix). +- `💡 has suggestions` refers to whether the rule contains an ESLint suggestion fixer. + - Sometimes, it is not safe to automatically fix the code with an auto-fixer. But in these cases, we often have a good guess of what the correct fix should be, and we can provide it as a suggestion to the developer. +- `💭 requires type information` refers to whether the rule requires [typed linting](/linting/typed-linting). +- `🧱 extension rule` means that the rule was originally a [core ESLint rule](https://eslint.org/docs/latest/rules/). + - Some core ESLint rules do not support TypeScript syntax: either they crash, ignore the syntax, or falsely report against it. + - In these cases, we create an "extension rule": a rule within our plugin that has the same functionality, but also supports TypeScript. +- `📐 formatting rule` means that the rule has to do with formatting. + - We [strongly recommend against using ESLint for formatting](/linting/troubleshooting/formatting). + - Soon, formatting rules will be moved to the [ESLint stylistic plugin](https://eslint.style). - `💀 deprecated rule` means that the rule should no longer be used and will be removed from the plugin in a future version. From 3d890b434a9fc5b2a3f370e1de0f4cfc33d80c33 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Tue, 17 Oct 2023 22:29:52 -0400 Subject: [PATCH 16/19] yarn format --- packages/website/src/components/RulesTable/index.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/website/src/components/RulesTable/index.tsx b/packages/website/src/components/RulesTable/index.tsx index f15bdcfe79bc..b4c1823b8c32 100644 --- a/packages/website/src/components/RulesTable/index.tsx +++ b/packages/website/src/components/RulesTable/index.tsx @@ -81,7 +81,8 @@ function RuleRow({ : undefined } > - {fixable ? FIXABLE_EMOJI : ''}
+ {fixable ? FIXABLE_EMOJI : ''} +
{hasSuggestions ? SUGGESTIONS_EMOJI : ''}
Date: Wed, 18 Oct 2023 09:31:32 -0400 Subject: [PATCH 17/19] Added explicit Extension Rules heading --- packages/eslint-plugin/docs/rules/README.md | 25 ++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/packages/eslint-plugin/docs/rules/README.md b/packages/eslint-plugin/docs/rules/README.md index 01ea7f19f849..4b6f9df42dc9 100644 --- a/packages/eslint-plugin/docs/rules/README.md +++ b/packages/eslint-plugin/docs/rules/README.md @@ -32,10 +32,29 @@ import RulesTable from "@site/src/components/RulesTable"; - `💡 has suggestions` refers to whether the rule contains an ESLint suggestion fixer. - Sometimes, it is not safe to automatically fix the code with an auto-fixer. But in these cases, we often have a good guess of what the correct fix should be, and we can provide it as a suggestion to the developer. - `💭 requires type information` refers to whether the rule requires [typed linting](/linting/typed-linting). -- `🧱 extension rule` means that the rule was originally a [core ESLint rule](https://eslint.org/docs/latest/rules/). - - Some core ESLint rules do not support TypeScript syntax: either they crash, ignore the syntax, or falsely report against it. - - In these cases, we create an "extension rule": a rule within our plugin that has the same functionality, but also supports TypeScript. +- `🧱 extension rule` means that the rule is an extension of an [core ESLint rule](https://eslint.org/docs/latest/rules) (see [Extension Rules](#extension-rules)). - `📐 formatting rule` means that the rule has to do with formatting. - We [strongly recommend against using ESLint for formatting](/linting/troubleshooting/formatting). - Soon, formatting rules will be moved to the [ESLint stylistic plugin](https://eslint.style). - `💀 deprecated rule` means that the rule should no longer be used and will be removed from the plugin in a future version. + +## Extension Rules + +Some core ESLint rules do not support TypeScript syntax: either they crash, ignore the syntax, or falsely report against it. +In these cases, we create what we call an "extension rule": a rule within our plugin that has the same functionality, but also supports TypeScript. + +Extension rules generally completely replace the base rule from ESLint core. +If the base rule is enabled in a config you extend from, you'll need to disable the base rule: + +```js +module.exports = { + extends: ['eslint:recommended'], + rules: { + // Note: you must disable the base rule as it can report incorrect errors + 'class-methods-use-this': 'off', + '@typescript-eslint/class-methods-use-this': 'error', + }, +}; +``` + +[Search for `🧱 extension rule`s](?=extension#rules) in this page to see all extension rules. From 0b64bad89217e5fc1f31679d912114578bac8291 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Wed, 18 Oct 2023 09:59:01 -0400 Subject: [PATCH 18/19] class-methods-use-this isn't actually in eslint:recommended --- packages/eslint-plugin/docs/rules/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/eslint-plugin/docs/rules/README.md b/packages/eslint-plugin/docs/rules/README.md index 4b6f9df42dc9..4d76d15d4f67 100644 --- a/packages/eslint-plugin/docs/rules/README.md +++ b/packages/eslint-plugin/docs/rules/README.md @@ -51,8 +51,8 @@ module.exports = { extends: ['eslint:recommended'], rules: { // Note: you must disable the base rule as it can report incorrect errors - 'class-methods-use-this': 'off', - '@typescript-eslint/class-methods-use-this': 'error', + 'dot-notation': 'off', + '@typescript-eslint/dot-notation': 'error', }, }; ``` From 49ec74582ac626f50c864bcc52225dac9bea0430 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Wed, 18 Oct 2023 10:03:44 -0400 Subject: [PATCH 19/19] no-unused-vars actually --- packages/eslint-plugin/docs/rules/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/eslint-plugin/docs/rules/README.md b/packages/eslint-plugin/docs/rules/README.md index 4d76d15d4f67..7b4d4dde58ed 100644 --- a/packages/eslint-plugin/docs/rules/README.md +++ b/packages/eslint-plugin/docs/rules/README.md @@ -51,8 +51,8 @@ module.exports = { extends: ['eslint:recommended'], rules: { // Note: you must disable the base rule as it can report incorrect errors - 'dot-notation': 'off', - '@typescript-eslint/dot-notation': 'error', + 'no-unused-vars': 'off', + '@typescript-eslint/no-unused-vars': 'error', }, }; ```