diff --git a/docs/linting/README.md b/docs/linting/README.md index 65081f42fc8..4011a309940 100644 --- a/docs/linting/README.md +++ b/docs/linting/README.md @@ -94,7 +94,7 @@ If you use [`prettier`](https://www.npmjs.com/package/prettier), there is also a Using this config by adding it to the end of your `extends`: -```diff +```diff title=".eslintrc.js" module.exports = { root: true, parser: '@typescript-eslint/parser', @@ -121,7 +121,7 @@ A few popular all-in-one configs are: To use one of these complete config packages, you would replace the `extends` with the package name. For example: -```diff +```diff title=".eslintrc.js" module.exports = { root: true, parser: '@typescript-eslint/parser', @@ -154,7 +154,7 @@ Below are just a few examples: Every plugin that is out there includes documentation on the various configurations and rules they offer. A typical plugin might be used like: -```diff +```diff title=".eslintrc.js" module.exports = { root: true, parser: '@typescript-eslint/parser', diff --git a/packages/eslint-plugin/docs/rules/README.md b/packages/eslint-plugin/docs/rules/README.md new file mode 100644 index 00000000000..205e1627334 --- /dev/null +++ b/packages/eslint-plugin/docs/rules/README.md @@ -0,0 +1,159 @@ +--- +title: Overview +sidebar_label: Overview +pagination_next: null +pagination_prev: null +slug: / +--- + +`@typescript-eslint/eslint-plugin` comes with two rulesets you can extend from to pull in the recommended starting rules: + +- `'plugin:@typescript-eslint/recommended'`: recommended rules for code correctness that you can drop in without additional configuration. + See [Linting](/docs/linting/linting) for more details. +- `'plugin:@typescript-eslint/recommended-requiring-type-checking'` additional recommended rules that require type information. + See [Linting](/docs/linting/type-linting) for more details. + +## Supported Rules + + + +**Key**: :white_check_mark: = recommended, :wrench: = fixable, :thought_balloon: = requires type information + +| Name | Description | :white_check_mark: | :wrench: | :thought_balloon: | +| ------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------- | ------------------ | -------- | ----------------- | +| [`@typescript-eslint/adjacent-overload-signatures`](./adjacent-overload-signatures.md) | Require that member overloads be consecutive | :white_check_mark: | | | +| [`@typescript-eslint/array-type`](./array-type.md) | Requires using either `T[]` or `Array` for arrays | | :wrench: | | +| [`@typescript-eslint/await-thenable`](./await-thenable.md) | Disallows awaiting a value that is not a Thenable | :white_check_mark: | | :thought_balloon: | +| [`@typescript-eslint/ban-ts-comment`](./ban-ts-comment.md) | Bans `@ts-` comments from being used or requires descriptions after directive | :white_check_mark: | | | +| [`@typescript-eslint/ban-tslint-comment`](./ban-tslint-comment.md) | Bans `// tslint:` comments from being used | | :wrench: | | +| [`@typescript-eslint/ban-types`](./ban-types.md) | Bans specific types from being used | :white_check_mark: | :wrench: | | +| [`@typescript-eslint/class-literal-property-style`](./class-literal-property-style.md) | Ensures that literals on classes are exposed in a consistent style | | :wrench: | | +| [`@typescript-eslint/consistent-indexed-object-style`](./consistent-indexed-object-style.md) | Enforce or disallow the use of the record type | | :wrench: | | +| [`@typescript-eslint/consistent-type-assertions`](./consistent-type-assertions.md) | Enforces consistent usage of type assertions | | | | +| [`@typescript-eslint/consistent-type-definitions`](./consistent-type-definitions.md) | Consistent with type definition either `interface` or `type` | | :wrench: | | +| [`@typescript-eslint/consistent-type-exports`](./consistent-type-exports.md) | Enforces consistent usage of type exports | | :wrench: | :thought_balloon: | +| [`@typescript-eslint/consistent-type-imports`](./consistent-type-imports.md) | Enforces consistent usage of type imports | | :wrench: | | +| [`@typescript-eslint/explicit-function-return-type`](./explicit-function-return-type.md) | Require explicit return types on functions and class methods | | | | +| [`@typescript-eslint/explicit-member-accessibility`](./explicit-member-accessibility.md) | Require explicit accessibility modifiers on class properties and methods | | :wrench: | | +| [`@typescript-eslint/explicit-module-boundary-types`](./explicit-module-boundary-types.md) | Require explicit return and argument types on exported functions' and classes' public class methods | | | | +| [`@typescript-eslint/member-delimiter-style`](./member-delimiter-style.md) | Require a specific member delimiter style for interfaces and type literals | | :wrench: | | +| [`@typescript-eslint/member-ordering`](./member-ordering.md) | Require a consistent member declaration order | | | | +| [`@typescript-eslint/method-signature-style`](./method-signature-style.md) | Enforces using a particular method signature syntax. | | :wrench: | | +| [`@typescript-eslint/naming-convention`](./naming-convention.md) | Enforces naming conventions for everything across a codebase | | | :thought_balloon: | +| [`@typescript-eslint/no-base-to-string`](./no-base-to-string.md) | Requires that `.toString()` is only called on objects which provide useful information when stringified | | | :thought_balloon: | +| [`@typescript-eslint/no-confusing-non-null-assertion`](./no-confusing-non-null-assertion.md) | Disallow non-null assertion in locations that may be confusing | | :wrench: | | +| [`@typescript-eslint/no-confusing-void-expression`](./no-confusing-void-expression.md) | Requires expressions of type void to appear in statement position | | :wrench: | :thought_balloon: | +| [`@typescript-eslint/no-dynamic-delete`](./no-dynamic-delete.md) | Disallow the delete operator with computed key expressions | | :wrench: | | +| [`@typescript-eslint/no-empty-interface`](./no-empty-interface.md) | Disallow the declaration of empty interfaces | :white_check_mark: | :wrench: | | +| [`@typescript-eslint/no-explicit-any`](./no-explicit-any.md) | Disallow usage of the `any` type | :white_check_mark: | :wrench: | | +| [`@typescript-eslint/no-extra-non-null-assertion`](./no-extra-non-null-assertion.md) | Disallow extra non-null assertion | :white_check_mark: | :wrench: | | +| [`@typescript-eslint/no-extraneous-class`](./no-extraneous-class.md) | Forbids the use of classes as namespaces | | | | +| [`@typescript-eslint/no-floating-promises`](./no-floating-promises.md) | Requires Promise-like values to be handled appropriately | :white_check_mark: | | :thought_balloon: | +| [`@typescript-eslint/no-for-in-array`](./no-for-in-array.md) | Disallow iterating over an array with a for-in loop | :white_check_mark: | | :thought_balloon: | +| [`@typescript-eslint/no-inferrable-types`](./no-inferrable-types.md) | Disallows explicit type declarations for variables or parameters initialized to a number, string, or boolean | :white_check_mark: | :wrench: | | +| [`@typescript-eslint/no-invalid-void-type`](./no-invalid-void-type.md) | Disallows usage of `void` type outside of generic or return types | | | | +| [`@typescript-eslint/no-meaningless-void-operator`](./no-meaningless-void-operator.md) | Disallow the `void` operator except when used to discard a value | | :wrench: | :thought_balloon: | +| [`@typescript-eslint/no-misused-new`](./no-misused-new.md) | Enforce valid definition of `new` and `constructor` | :white_check_mark: | | | +| [`@typescript-eslint/no-misused-promises`](./no-misused-promises.md) | Avoid using promises in places not designed to handle them | :white_check_mark: | | :thought_balloon: | +| [`@typescript-eslint/no-namespace`](./no-namespace.md) | Disallow the use of custom TypeScript modules and namespaces | :white_check_mark: | | | +| [`@typescript-eslint/no-non-null-asserted-nullish-coalescing`](./no-non-null-asserted-nullish-coalescing.md) | Disallows using a non-null assertion in the left operand of the nullish coalescing operator | | | | +| [`@typescript-eslint/no-non-null-asserted-optional-chain`](./no-non-null-asserted-optional-chain.md) | Disallows using a non-null assertion after an optional chain expression | :white_check_mark: | | | +| [`@typescript-eslint/no-non-null-assertion`](./no-non-null-assertion.md) | Disallows non-null assertions using the `!` postfix operator | :white_check_mark: | | | +| [`@typescript-eslint/no-parameter-properties`](./no-parameter-properties.md) | Disallow the use of parameter properties in class constructors | | | | +| [`@typescript-eslint/no-require-imports`](./no-require-imports.md) | Disallows invocation of `require()` | | | | +| [`@typescript-eslint/no-this-alias`](./no-this-alias.md) | Disallow aliasing `this` | :white_check_mark: | | | +| [`@typescript-eslint/no-type-alias`](./no-type-alias.md) | Disallow the use of type aliases | | | | +| [`@typescript-eslint/no-unnecessary-boolean-literal-compare`](./no-unnecessary-boolean-literal-compare.md) | Flags unnecessary equality comparisons against boolean literals | | :wrench: | :thought_balloon: | +| [`@typescript-eslint/no-unnecessary-condition`](./no-unnecessary-condition.md) | Prevents conditionals where the type is always truthy or always falsy | | :wrench: | :thought_balloon: | +| [`@typescript-eslint/no-unnecessary-qualifier`](./no-unnecessary-qualifier.md) | Warns when a namespace qualifier is unnecessary | | :wrench: | :thought_balloon: | +| [`@typescript-eslint/no-unnecessary-type-arguments`](./no-unnecessary-type-arguments.md) | Enforces that type arguments will not be used if not required | | :wrench: | :thought_balloon: | +| [`@typescript-eslint/no-unnecessary-type-assertion`](./no-unnecessary-type-assertion.md) | Warns if a type assertion does not change the type of an expression | :white_check_mark: | :wrench: | :thought_balloon: | +| [`@typescript-eslint/no-unnecessary-type-constraint`](./no-unnecessary-type-constraint.md) | Disallows unnecessary constraints on generic types | :white_check_mark: | :wrench: | | +| [`@typescript-eslint/no-unsafe-argument`](./no-unsafe-argument.md) | Disallows calling a function with an any type value | :white_check_mark: | | :thought_balloon: | +| [`@typescript-eslint/no-unsafe-assignment`](./no-unsafe-assignment.md) | Disallows assigning any to variables and properties | :white_check_mark: | | :thought_balloon: | +| [`@typescript-eslint/no-unsafe-call`](./no-unsafe-call.md) | Disallows calling an any type value | :white_check_mark: | | :thought_balloon: | +| [`@typescript-eslint/no-unsafe-member-access`](./no-unsafe-member-access.md) | Disallows member access on any typed variables | :white_check_mark: | | :thought_balloon: | +| [`@typescript-eslint/no-unsafe-return`](./no-unsafe-return.md) | Disallows returning any from a function | :white_check_mark: | | :thought_balloon: | +| [`@typescript-eslint/no-var-requires`](./no-var-requires.md) | Disallows the use of require statements except in import statements | :white_check_mark: | | | +| [`@typescript-eslint/non-nullable-type-assertion-style`](./non-nullable-type-assertion-style.md) | Prefers a non-null assertion over explicit type cast when possible | | :wrench: | :thought_balloon: | +| [`@typescript-eslint/prefer-as-const`](./prefer-as-const.md) | Prefer usage of `as const` over literal type | :white_check_mark: | :wrench: | | +| [`@typescript-eslint/prefer-enum-initializers`](./prefer-enum-initializers.md) | Prefer initializing each enums member value | | | | +| [`@typescript-eslint/prefer-for-of`](./prefer-for-of.md) | Prefer a ‘for-of’ loop over a standard ‘for’ loop if the index is only used to access the array being iterated | | | | +| [`@typescript-eslint/prefer-function-type`](./prefer-function-type.md) | Use function types instead of interfaces with call signatures | | :wrench: | | +| [`@typescript-eslint/prefer-includes`](./prefer-includes.md) | Enforce `includes` method over `indexOf` method | | :wrench: | :thought_balloon: | +| [`@typescript-eslint/prefer-literal-enum-member`](./prefer-literal-enum-member.md) | Require that all enum members be literal values to prevent unintended enum member name shadow issues | | | | +| [`@typescript-eslint/prefer-namespace-keyword`](./prefer-namespace-keyword.md) | Require the use of the `namespace` keyword instead of the `module` keyword to declare custom TypeScript modules | :white_check_mark: | :wrench: | | +| [`@typescript-eslint/prefer-nullish-coalescing`](./prefer-nullish-coalescing.md) | Enforce the usage of the nullish coalescing operator instead of logical chaining | | | :thought_balloon: | +| [`@typescript-eslint/prefer-optional-chain`](./prefer-optional-chain.md) | Prefer using concise optional chain expressions instead of chained logical ands | | | | +| [`@typescript-eslint/prefer-readonly`](./prefer-readonly.md) | Requires that private members are marked as `readonly` if they're never modified outside of the constructor | | :wrench: | :thought_balloon: | +| [`@typescript-eslint/prefer-readonly-parameter-types`](./prefer-readonly-parameter-types.md) | Requires that function parameters are typed as readonly to prevent accidental mutation of inputs | | | :thought_balloon: | +| [`@typescript-eslint/prefer-reduce-type-parameter`](./prefer-reduce-type-parameter.md) | Prefer using type parameter when calling `Array#reduce` instead of casting | | :wrench: | :thought_balloon: | +| [`@typescript-eslint/prefer-regexp-exec`](./prefer-regexp-exec.md) | Enforce that `RegExp#exec` is used instead of `String#match` if no global flag is provided | | :wrench: | :thought_balloon: | +| [`@typescript-eslint/prefer-return-this-type`](./prefer-return-this-type.md) | Enforce that `this` is used when only `this` type is returned | | :wrench: | :thought_balloon: | +| [`@typescript-eslint/prefer-string-starts-ends-with`](./prefer-string-starts-ends-with.md) | Enforce the use of `String#startsWith` and `String#endsWith` instead of other equivalent methods of checking substrings | | :wrench: | :thought_balloon: | +| [`@typescript-eslint/prefer-ts-expect-error`](./prefer-ts-expect-error.md) | Recommends using `@ts-expect-error` over `@ts-ignore` | | :wrench: | | +| [`@typescript-eslint/promise-function-async`](./promise-function-async.md) | Requires any function or method that returns a Promise to be marked async | | :wrench: | :thought_balloon: | +| [`@typescript-eslint/require-array-sort-compare`](./require-array-sort-compare.md) | Requires `Array#sort` calls to always provide a `compareFunction` | | | :thought_balloon: | +| [`@typescript-eslint/restrict-plus-operands`](./restrict-plus-operands.md) | When adding two variables, operands must both be of type number or of type string | :white_check_mark: | | :thought_balloon: | +| [`@typescript-eslint/restrict-template-expressions`](./restrict-template-expressions.md) | Enforce template literal expressions to be of string type | :white_check_mark: | | :thought_balloon: | +| [`@typescript-eslint/sort-type-union-intersection-members`](./sort-type-union-intersection-members.md) | Enforces that members of a type union/intersection are sorted alphabetically | | :wrench: | | +| [`@typescript-eslint/strict-boolean-expressions`](./strict-boolean-expressions.md) | Restricts the types allowed in boolean expressions | | :wrench: | :thought_balloon: | +| [`@typescript-eslint/switch-exhaustiveness-check`](./switch-exhaustiveness-check.md) | Exhaustiveness checking in switch with union type | | | :thought_balloon: | +| [`@typescript-eslint/triple-slash-reference`](./triple-slash-reference.md) | Sets preference level for triple slash directives versus ES6-style import declarations | :white_check_mark: | | | +| [`@typescript-eslint/type-annotation-spacing`](./type-annotation-spacing.md) | Require consistent spacing around type annotations | | :wrench: | | +| [`@typescript-eslint/typedef`](./typedef.md) | Requires type annotations to exist | | | | +| [`@typescript-eslint/unbound-method`](./unbound-method.md) | Enforces unbound methods are called with their expected scope | :white_check_mark: | | :thought_balloon: | +| [`@typescript-eslint/unified-signatures`](./unified-signatures.md) | Warns for any two overloads that could be unified into one by using a union or an optional/rest parameter | | | | + + + +### Extension Rules + +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. + + + +**Key**: :white_check_mark: = recommended, :wrench: = fixable, :thought_balloon: = requires type information + +| Name | Description | :white_check_mark: | :wrench: | :thought_balloon: | +| -------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ | ------------------ | -------- | ----------------- | +| [`@typescript-eslint/brace-style`](./brace-style.md) | Enforce consistent brace style for blocks | | :wrench: | | +| [`@typescript-eslint/comma-dangle`](./comma-dangle.md) | Require or disallow trailing comma | | :wrench: | | +| [`@typescript-eslint/comma-spacing`](./comma-spacing.md) | Enforces consistent spacing before and after commas | | :wrench: | | +| [`@typescript-eslint/default-param-last`](./default-param-last.md) | Enforce default parameters to be last | | | | +| [`@typescript-eslint/dot-notation`](./dot-notation.md) | enforce dot notation whenever possible | | :wrench: | :thought_balloon: | +| [`@typescript-eslint/func-call-spacing`](./func-call-spacing.md) | Require or disallow spacing between function identifiers and their invocations | | :wrench: | | +| [`@typescript-eslint/indent`](./indent.md) | Enforce consistent indentation | | :wrench: | | +| [`@typescript-eslint/init-declarations`](./init-declarations.md) | require or disallow initialization in variable declarations | | | | +| [`@typescript-eslint/keyword-spacing`](./keyword-spacing.md) | Enforce consistent spacing before and after keywords | | :wrench: | | +| [`@typescript-eslint/lines-between-class-members`](./lines-between-class-members.md) | Require or disallow an empty line between class members | | :wrench: | | +| [`@typescript-eslint/no-array-constructor`](./no-array-constructor.md) | Disallow generic `Array` constructors | :white_check_mark: | :wrench: | | +| [`@typescript-eslint/no-dupe-class-members`](./no-dupe-class-members.md) | Disallow duplicate class members | | | | +| [`@typescript-eslint/no-duplicate-imports`](./no-duplicate-imports.md) | Disallow duplicate imports | | | | +| [`@typescript-eslint/no-empty-function`](./no-empty-function.md) | Disallow empty functions | :white_check_mark: | | | +| [`@typescript-eslint/no-extra-parens`](./no-extra-parens.md) | Disallow unnecessary parentheses | | :wrench: | | +| [`@typescript-eslint/no-extra-semi`](./no-extra-semi.md) | Disallow unnecessary semicolons | :white_check_mark: | :wrench: | | +| [`@typescript-eslint/no-implied-eval`](./no-implied-eval.md) | Disallow the use of `eval()`-like methods | :white_check_mark: | | :thought_balloon: | +| [`@typescript-eslint/no-invalid-this`](./no-invalid-this.md) | Disallow `this` keywords outside of classes or class-like objects | | | | +| [`@typescript-eslint/no-loop-func`](./no-loop-func.md) | Disallow function declarations that contain unsafe references inside loop statements | | | | +| [`@typescript-eslint/no-loss-of-precision`](./no-loss-of-precision.md) | Disallow literal numbers that lose precision | :white_check_mark: | | | +| [`@typescript-eslint/no-magic-numbers`](./no-magic-numbers.md) | Disallow magic numbers | | | | +| [`@typescript-eslint/no-redeclare`](./no-redeclare.md) | Disallow variable redeclaration | | | | +| [`@typescript-eslint/no-restricted-imports`](./no-restricted-imports.md) | Disallow specified modules when loaded by `import` | | | | +| [`@typescript-eslint/no-shadow`](./no-shadow.md) | Disallow variable declarations from shadowing variables declared in the outer scope | | | | +| [`@typescript-eslint/no-throw-literal`](./no-throw-literal.md) | Disallow throwing literals as exceptions | | | :thought_balloon: | +| [`@typescript-eslint/no-unused-expressions`](./no-unused-expressions.md) | Disallow unused expressions | | | | +| [`@typescript-eslint/no-unused-vars`](./no-unused-vars.md) | Disallow unused variables | :white_check_mark: | | | +| [`@typescript-eslint/no-use-before-define`](./no-use-before-define.md) | Disallow the use of variables before they are defined | | | | +| [`@typescript-eslint/no-useless-constructor`](./no-useless-constructor.md) | Disallow unnecessary constructors | | | | +| [`@typescript-eslint/object-curly-spacing`](./object-curly-spacing.md) | Enforce consistent spacing inside braces | | :wrench: | | +| [`@typescript-eslint/padding-line-between-statements`](./padding-line-between-statements.md) | require or disallow padding lines between statements | | :wrench: | | +| [`@typescript-eslint/quotes`](./quotes.md) | Enforce the consistent use of either backticks, double, or single quotes | | :wrench: | | +| [`@typescript-eslint/require-await`](./require-await.md) | Disallow async functions which have no `await` expression | :white_check_mark: | | :thought_balloon: | +| [`@typescript-eslint/return-await`](./return-await.md) | Enforces consistent returning of awaited values | | :wrench: | :thought_balloon: | +| [`@typescript-eslint/semi`](./semi.md) | Require or disallow semicolons instead of ASI | | :wrench: | | +| [`@typescript-eslint/space-before-function-paren`](./space-before-function-paren.md) | Enforces consistent spacing before function parenthesis | | :wrench: | | +| [`@typescript-eslint/space-infix-ops`](./space-infix-ops.md) | This rule is aimed at ensuring there are spaces around infix operators. | | :wrench: | | + + diff --git a/packages/eslint-plugin/docs/rules/comma-dangle.md b/packages/eslint-plugin/docs/rules/comma-dangle.md index 6db276e59d9..035248bcd46 100644 --- a/packages/eslint-plugin/docs/rules/comma-dangle.md +++ b/packages/eslint-plugin/docs/rules/comma-dangle.md @@ -9,7 +9,7 @@ See the [ESLint documentation](https://eslint.org/docs/rules/comma-dangle) for m ## Rule Changes -```cjson +```jsonc { // note you must disable the base rule as it can report incorrect errors "comma-dangle": "off", diff --git a/packages/eslint-plugin/docs/rules/member-delimiter-style.md b/packages/eslint-plugin/docs/rules/member-delimiter-style.md index 259915f7b41..966a1a7fbda 100644 --- a/packages/eslint-plugin/docs/rules/member-delimiter-style.md +++ b/packages/eslint-plugin/docs/rules/member-delimiter-style.md @@ -78,17 +78,17 @@ type Config = BaseConfig & { Default config: -```JSON +```json { - "multiline": { - "delimiter": "semi", - "requireLast": true - }, - "singleline": { - "delimiter": "semi", - "requireLast": false - }, - "multilineDetection": "brackets" + "multiline": { + "delimiter": "semi", + "requireLast": true + }, + "singleline": { + "delimiter": "semi", + "requireLast": false + }, + "multilineDetection": "brackets" } ``` @@ -108,7 +108,10 @@ Accepts three values (or two for `singleline`): - `comma` - each member should be delimited with a comma (`,`). - `semi` - each member should be delimited with a semicolon (`;`). - `none` - each member should be delimited with nothing. - - NOTE - this is not an option for `singleline` because having no delimiter between members on a single line is a syntax error in TS. + +:::note +`none` is not an option for `singleline` because having no delimiter between members on a single line is a syntax error in TS. +::: ### `requireLast` @@ -123,24 +126,24 @@ Allows you to specify options specifically for either `interface`s or `type` def For example, to require commas for `type`s, and semicolons for multiline `interface`s: -```JSON +```json { - "multiline": { - "delimiter": "comma", - "requireLast": true - }, - "singleline": { - "delimiter": "comma", + "multiline": { + "delimiter": "comma", + "requireLast": true + }, + "singleline": { + "delimiter": "comma", + "requireLast": true + }, + "overrides": { + "interface": { + "multiline": { + "delimiter": "semi", "requireLast": true - }, - "overrides": { - "interface": { - "multiline": { - "delimiter": "semi", - "requireLast": true - } - } + } } + } } ``` diff --git a/packages/eslint-plugin/docs/rules/no-inferrable-types.md b/packages/eslint-plugin/docs/rules/no-inferrable-types.md index cde64f5b73d..f94c58671f8 100644 --- a/packages/eslint-plugin/docs/rules/no-inferrable-types.md +++ b/packages/eslint-plugin/docs/rules/no-inferrable-types.md @@ -22,10 +22,10 @@ interface Options { The default options are: -```JSON +```json { "ignoreParameters": false, - "ignoreProperties": false, + "ignoreProperties": false } ``` diff --git a/packages/eslint-plugin/docs/rules/object-curly-spacing.md b/packages/eslint-plugin/docs/rules/object-curly-spacing.md index 7fec0a16493..cccc94747d8 100644 --- a/packages/eslint-plugin/docs/rules/object-curly-spacing.md +++ b/packages/eslint-plugin/docs/rules/object-curly-spacing.md @@ -7,7 +7,7 @@ It adds support for TypeScript's object types. ## How to use -```cjson +```jsonc { // note you must disable the base rule as it can report incorrect errors "object-curly-spacing": "off", diff --git a/packages/eslint-plugin/docs/rules/prefer-string-starts-ends-with.md b/packages/eslint-plugin/docs/rules/prefer-string-starts-ends-with.md index 729da937307..0979653f856 100644 --- a/packages/eslint-plugin/docs/rules/prefer-string-starts-ends-with.md +++ b/packages/eslint-plugin/docs/rules/prefer-string-starts-ends-with.md @@ -43,9 +43,9 @@ foo.endsWith('bar'); There are no options. -```JSON +```json { - "@typescript-eslint/prefer-string-starts-ends-with": "error" + "@typescript-eslint/prefer-string-starts-ends-with": "error" } ``` diff --git a/packages/eslint-plugin/docs/rules/require-array-sort-compare.md b/packages/eslint-plugin/docs/rules/require-array-sort-compare.md index 2f0fd2681fb..f05bd66e9f5 100644 --- a/packages/eslint-plugin/docs/rules/require-array-sort-compare.md +++ b/packages/eslint-plugin/docs/rules/require-array-sort-compare.md @@ -13,7 +13,11 @@ When sorting numbers, this results in the classic "10 before 2" order: This also means that `Array#sort` does not always sort consistently, as elements may have custom `#toString` implementations that are not deterministic; this trap is noted in the language specification thusly: -> NOTE 2: Method calls performed by the `ToString` abstract operations in steps 5 and 7 have the potential to cause `SortCompare` to not behave as a consistent comparison function.
> https://www.ecma-international.org/ecma-262/9.0/#sec-sortcompare +:::note +Method calls performed by the `ToString` abstract operations in steps 5 and 7 have the potential to cause `SortCompare` to not behave as a consistent comparison function. + +https://www.ecma-international.org/ecma-262/9.0/#sec-sortcompare +::: ## Rule Details diff --git a/packages/eslint-plugin/tests/docs.test.ts b/packages/eslint-plugin/tests/docs.test.ts index e0ab041c160..42c8af85ce6 100644 --- a/packages/eslint-plugin/tests/docs.test.ts +++ b/packages/eslint-plugin/tests/docs.test.ts @@ -44,7 +44,7 @@ describe('Validating rule docs', () => { const files = fs .readdirSync(docsRoot) // this rule doc was left behind on purpose for legacy reasons - .filter(rule => rule !== 'camelcase.md'); + .filter(rule => rule !== 'camelcase.md' && rule !== 'README.md'); const ruleFiles = Object.keys(rules) .map(rule => `${rule}.md`) .sort(); diff --git a/packages/eslint-plugin/tools/generate-rules-lists.ts b/packages/eslint-plugin/tools/generate-rules-lists.ts index a4d3f3af8e7..d508f9e8330 100644 --- a/packages/eslint-plugin/tools/generate-rules-lists.ts +++ b/packages/eslint-plugin/tools/generate-rules-lists.ts @@ -51,33 +51,41 @@ const returnEmojiIfTrue = ( obj: { [K in TKey]?: unknown }, ): typeof emojiKey[TKey] | '' => (obj[key] ? emojiKey[key] : ''); -const createRuleLink = (ruleName: string): string => - `[\`@typescript-eslint/${ruleName}\`](./docs/rules/${ruleName}.md)`; +const createRuleLink = (ruleName: string, basePath: string): string => + `[\`@typescript-eslint/${ruleName}\`](${basePath}${ruleName}.md)`; -const buildRuleRow = (rule: RuleDetails): RuleColumn => [ - createRuleLink(rule.name), +const buildRuleRow = (rule: RuleDetails, basePath: string): RuleColumn => [ + createRuleLink(rule.name, basePath), rule.description, returnEmojiIfTrue('recommended', rule), returnEmojiIfTrue('fixable', rule), returnEmojiIfTrue('requiresTypeChecking', rule), ]; -const buildRulesTable = (rules: RuleDetails[]): string[][] => [ +const buildRulesTable = ( + rules: RuleDetails[], + basePath: string, +): string[][] => [ staticElements.listHeaderRow, staticElements.listSpacerRow, ...rules .sort(({ name: ruleNameA }, { name: ruleNameB }) => ruleNameA.localeCompare(ruleNameB), ) - .map(buildRuleRow), + .map(item => buildRuleRow(item, basePath)), ]; -const generateRulesListMarkdown = (rules: RuleDetails[]): string => +const generateRulesListMarkdown = ( + rules: RuleDetails[], + basePath: string, +): string => [ '', staticElements.rulesListKey, '', - ...buildRulesTable(rules).map(column => [...column, ' '].join('|')), + ...buildRulesTable(rules, basePath).map(column => + [...column, ' '].join('|'), + ), '', ].join('\n'); @@ -85,6 +93,7 @@ const updateRulesList = ( listName: 'base' | 'extension', rules: RuleDetails[], markdown: string, + basePath: string, ): string => { const listBeginMarker = ``; const listEndMarker = ``; @@ -100,7 +109,7 @@ const updateRulesList = ( markdown.substring(0, listStartIndex - 1), listBeginMarker, '', - generateRulesListMarkdown(rules), // + generateRulesListMarkdown(rules, basePath), // markdown.substring(listEndIndex), ].join('\n'); }; @@ -119,11 +128,16 @@ const rulesDetails: RuleDetails[] = Object.entries(rules) const baseRules = rulesDetails.filter(rule => !rule.extendsBaseRule); const extensionRules = rulesDetails.filter(rule => rule.extendsBaseRule); -let readme = fs.readFileSync(path.resolve(__dirname, '../README.md'), 'utf8'); +function updateFile(file: string, basePath: string): void { + let readme = fs.readFileSync(file, 'utf8'); -readme = updateRulesList('base', baseRules, readme); -readme = updateRulesList('extension', extensionRules, readme); + readme = updateRulesList('base', baseRules, readme, basePath); + readme = updateRulesList('extension', extensionRules, readme, basePath); -readme = prettier.format(readme, { parser: 'markdown' }); + readme = prettier.format(readme, { parser: 'markdown' }); + + fs.writeFileSync(file, readme, 'utf8'); +} -fs.writeFileSync(path.resolve(__dirname, '../README.md'), readme, 'utf8'); +updateFile(path.resolve(__dirname, '../README.md'), './docs/rules/'); +updateFile(path.resolve(__dirname, '../docs/rules/README.md'), './'); diff --git a/packages/website/docusaurus.config.js b/packages/website/docusaurus.config.js index dd08fa3e582..f46afb18767 100644 --- a/packages/website/docusaurus.config.js +++ b/packages/website/docusaurus.config.js @@ -80,7 +80,7 @@ const config = { position: 'left', }, { - to: 'rules/ban-types', + to: 'rules/', activeBasePath: 'rules', label: 'Rules', position: 'left', diff --git a/packages/website/sidebars/sidebar.rules.js b/packages/website/sidebars/sidebar.rules.js index e88c705a4f3..5f97f8b6241 100644 --- a/packages/website/sidebars/sidebar.rules.js +++ b/packages/website/sidebars/sidebar.rules.js @@ -1,19 +1,60 @@ const globby = require('globby'); const path = require('path'); -const paths = globby.sync('*.md', { - cwd: path.join(__dirname, '../../eslint-plugin/docs/rules'), +const plugin = require('@typescript-eslint/eslint-plugin'); + +const rules = Object.entries(plugin.rules).map(([name, rule]) => { + return { + name: name, + meta: { ...rule.meta }, + }; }); +const notDeprecatedRules = rules.filter(rule => !rule.meta.deprecated); + +const deprecatedRules = rules.filter(rule => rule.meta.deprecated); + +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' && !rules.some(a => a.name === item.name); + }); + module.exports = { - someSidebar: { - Rules: paths.map(item => { - const name = path.basename(item, '.md'); - return { - type: 'doc', - id: name, - label: name, - }; - }), - }, + someSidebar: [ + 'README', + { + type: 'category', + label: 'Rules', + collapsible: true, + collapsed: false, + items: notDeprecatedRules.map(item => { + return { + type: 'doc', + id: item.name, + label: item.name, + }; + }), + }, + { + type: 'category', + label: 'Deprecated', + collapsible: true, + collapsed: false, + items: [...deprecatedRules, ...paths].map(item => { + return { + type: 'doc', + id: item.name, + label: item.name, + }; + }), + }, + ], };