diff --git a/.cspell.json b/.cspell.json index ec11ebf5018d..080101b25f08 100644 --- a/.cspell.json +++ b/.cspell.json @@ -119,6 +119,7 @@ "serializers", "Sourcegraph", "stringification", + "stringifying", "stringly", "superset", "thenables", diff --git a/packages/eslint-plugin/docs/rules/adjacent-overload-signatures.md b/packages/eslint-plugin/docs/rules/adjacent-overload-signatures.md index b221b4497240..50b96b83639c 100644 --- a/packages/eslint-plugin/docs/rules/adjacent-overload-signatures.md +++ b/packages/eslint-plugin/docs/rules/adjacent-overload-signatures.md @@ -90,4 +90,10 @@ export function foo(sn: string | number): void; ## When Not To Use It -If you don't care about the general structure of the code, then you will not need this rule. +It can sometimes be useful to place overload signatures alongside other meaningful parts of a type. +For example, if each of a function's overloads corresponds to a different property, you might wish to put each overloads next to its corresponding property. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. + +## Related To + +- [`unified-signatures`](./unified-signatures.md) diff --git a/packages/eslint-plugin/docs/rules/array-type.md b/packages/eslint-plugin/docs/rules/array-type.md index 19b0c319d51f..e04635d607e8 100644 --- a/packages/eslint-plugin/docs/rules/array-type.md +++ b/packages/eslint-plugin/docs/rules/array-type.md @@ -101,3 +101,11 @@ This matrix lists all possible option combinations and their expected results fo | `generic` | `array` | `Array` | `Array` | `readonly number[]` | `readonly (Foo & Bar)[]` | | `generic` | `array-simple` | `Array` | `Array` | `readonly number[]` | `ReadonlyArray` | | `generic` | `generic` | `Array` | `Array` | `ReadonlyArray` | `ReadonlyArray` | + +## When Not To Use It + +This rule is purely a stylistic rule for maintaining consistency in your project. +You can turn it off if you don't want to keep a consistent style for array types. + +However, keep in mind that inconsistent style can harm readability in a project. +We recommend picking a single option for this rule that works best for your project. diff --git a/packages/eslint-plugin/docs/rules/await-thenable.md b/packages/eslint-plugin/docs/rules/await-thenable.md index 49238bbfcf12..fa02a9f286d5 100644 --- a/packages/eslint-plugin/docs/rules/await-thenable.md +++ b/packages/eslint-plugin/docs/rules/await-thenable.md @@ -37,4 +37,6 @@ await createValue(); ## When Not To Use It If you want to allow code to `await` non-Promise values. -This is generally not preferred, but can sometimes be useful for visual consistency. +For example, if your framework is in transition from one style of asynchronous code to another, it may be useful to include `await`s unnecessarily. +This is generally not preferred but can sometimes be useful for visual consistency. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. diff --git a/packages/eslint-plugin/docs/rules/ban-ts-comment.md b/packages/eslint-plugin/docs/rules/ban-ts-comment.md index 742b29e2e928..cd62195fd47f 100644 --- a/packages/eslint-plugin/docs/rules/ban-ts-comment.md +++ b/packages/eslint-plugin/docs/rules/ban-ts-comment.md @@ -143,7 +143,8 @@ if (false) { ## When Not To Use It -If you want to use all of the TypeScript directives. +If your project or its dependencies were not architected with strong type safety in mind, it can be difficult to always adhere to proper TypeScript semantics. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. ## Further Reading diff --git a/packages/eslint-plugin/docs/rules/ban-tslint-comment.md b/packages/eslint-plugin/docs/rules/ban-tslint-comment.md index 96a5e9b91dbc..eac42f6cdabf 100644 --- a/packages/eslint-plugin/docs/rules/ban-tslint-comment.md +++ b/packages/eslint-plugin/docs/rules/ban-tslint-comment.md @@ -36,4 +36,4 @@ someCode(); // This is a comment that just happens to mention tslint ## When Not To Use It -If you are still using TSLint. +If you are still using TSLint alongside ESLint. diff --git a/packages/eslint-plugin/docs/rules/ban-types.md b/packages/eslint-plugin/docs/rules/ban-types.md index f52b24cf7e9f..818528451e09 100644 --- a/packages/eslint-plugin/docs/rules/ban-types.md +++ b/packages/eslint-plugin/docs/rules/ban-types.md @@ -125,3 +125,8 @@ Example configuration: ] } ``` + +## When Not To Use It + +If your project is a rare one that intentionally deals with the class equivalents of primitives, it might not be worthwhile to enable the default `ban-types` options. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. diff --git a/packages/eslint-plugin/docs/rules/class-literal-property-style.md b/packages/eslint-plugin/docs/rules/class-literal-property-style.md index 6d882f92caa9..8567bc3ca83b 100644 --- a/packages/eslint-plugin/docs/rules/class-literal-property-style.md +++ b/packages/eslint-plugin/docs/rules/class-literal-property-style.md @@ -102,5 +102,4 @@ class Mx { ## When Not To Use It -When you have no strong preference, or do not wish to enforce a particular style -for how literal values are exposed by your classes. +When you have no strong preference, or do not wish to enforce a particular style for how literal values are exposed by your classes. diff --git a/packages/eslint-plugin/docs/rules/class-methods-use-this.md b/packages/eslint-plugin/docs/rules/class-methods-use-this.md index 098d4c692b14..8864b44cf3aa 100644 --- a/packages/eslint-plugin/docs/rules/class-methods-use-this.md +++ b/packages/eslint-plugin/docs/rules/class-methods-use-this.md @@ -89,3 +89,8 @@ class X implements Y { property = () => {}; } ``` + +## When Not To Use It + +If your project dynamically changes `this` scopes around in a way TypeScript has difficulties modeling, this rule may not be viable to use. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. diff --git a/packages/eslint-plugin/docs/rules/consistent-generic-constructors.md b/packages/eslint-plugin/docs/rules/consistent-generic-constructors.md index 4f347ef069c9..6056a58dfec4 100644 --- a/packages/eslint-plugin/docs/rules/consistent-generic-constructors.md +++ b/packages/eslint-plugin/docs/rules/consistent-generic-constructors.md @@ -71,3 +71,6 @@ const set: Set = new Set(); ## When Not To Use It You can turn this rule off if you don't want to enforce one kind of generic constructor style over the other. + +However, keep in mind that inconsistent style can harm readability in a project. +We recommend picking a single option for this rule that works best for your project. diff --git a/packages/eslint-plugin/docs/rules/consistent-indexed-object-style.md b/packages/eslint-plugin/docs/rules/consistent-indexed-object-style.md index 3da4679e28b6..82321b4fe61e 100644 --- a/packages/eslint-plugin/docs/rules/consistent-indexed-object-style.md +++ b/packages/eslint-plugin/docs/rules/consistent-indexed-object-style.md @@ -70,3 +70,11 @@ type Foo = { [key: string]: unknown; }; ``` + +## When Not To Use It + +This rule is purely a stylistic rule for maintaining consistency in your project. +You can turn it off if you don't want to keep a consistent style for indexed object types. + +However, keep in mind that inconsistent style can harm readability in a project. +We recommend picking a single option for this rule that works best for your project. diff --git a/packages/eslint-plugin/docs/rules/consistent-type-assertions.md b/packages/eslint-plugin/docs/rules/consistent-type-assertions.md index 3e6f3fce6061..b453e7201aa6 100644 --- a/packages/eslint-plugin/docs/rules/consistent-type-assertions.md +++ b/packages/eslint-plugin/docs/rules/consistent-type-assertions.md @@ -106,3 +106,6 @@ const foo = ; ## When Not To Use It If you do not want to enforce consistent type assertions. + +However, keep in mind that inconsistent style can harm readability in a project. +We recommend picking a single option for this rule that works best for your project. diff --git a/packages/eslint-plugin/docs/rules/consistent-type-definitions.md b/packages/eslint-plugin/docs/rules/consistent-type-definitions.md index dd06eabe686a..4394e82f39ce 100644 --- a/packages/eslint-plugin/docs/rules/consistent-type-definitions.md +++ b/packages/eslint-plugin/docs/rules/consistent-type-definitions.md @@ -71,4 +71,11 @@ type T = { x: number }; ## When Not To Use It -If you specifically want to use an interface or type literal for stylistic reasons, you can disable this rule. +If you specifically want to use an interface or type literal for stylistic reasons, you can avoid this rule. + +However, keep in mind that inconsistent style can harm readability in a project. +We recommend picking a single option for this rule that works best for your project. + +There are also subtle differences between `Record` and `interface` that can be difficult to catch statically. +For example, if your project is a dependency of another project that relies on a specific type definition style, this rule may be counterproductive. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. diff --git a/packages/eslint-plugin/docs/rules/consistent-type-exports.md b/packages/eslint-plugin/docs/rules/consistent-type-exports.md index 0088d3fa5ba5..61f520845c5f 100644 --- a/packages/eslint-plugin/docs/rules/consistent-type-exports.md +++ b/packages/eslint-plugin/docs/rules/consistent-type-exports.md @@ -96,5 +96,10 @@ export { Button, type ButtonProps } from 'some-library'; ## When Not To Use It -- If you specifically want to use both export kinds for stylistic reasons, you can disable this rule. -- If you use `--isolatedModules` the compiler would error if a type is not re-exported using `export type`. If you also don't wish to enforce one style over the other, you can disable this rule. +If you use `--isolatedModules` the compiler would error if a type is not re-exported using `export type`. +This rule may be less useful in those cases. + +If you specifically want to use both export kinds for stylistic reasons, or don't wish to enforce one style over the other, you can avoid this rule. + +However, keep in mind that inconsistent style can harm readability in a project. +We recommend picking a single option for this rule that works best for your project. diff --git a/packages/eslint-plugin/docs/rules/consistent-type-imports.md b/packages/eslint-plugin/docs/rules/consistent-type-imports.md index 96e50791f3d3..496172f342e3 100644 --- a/packages/eslint-plugin/docs/rules/consistent-type-imports.md +++ b/packages/eslint-plugin/docs/rules/consistent-type-imports.md @@ -96,7 +96,10 @@ If you are using [type-aware linting](https://typescript-eslint.io/linting/typed ## When Not To Use It -- If you specifically want to use both import kinds for stylistic reasons, you can disable this rule. +If you specifically want to use both import kinds for stylistic reasons, or don't wish to enforce one style over the other, you can avoid this rule. + +However, keep in mind that inconsistent style can harm readability in a project. +We recommend picking a single option for this rule that works best for your project. ## Related To diff --git a/packages/eslint-plugin/docs/rules/dot-notation.md b/packages/eslint-plugin/docs/rules/dot-notation.md index afb2c352844a..8d939219bb2d 100644 --- a/packages/eslint-plugin/docs/rules/dot-notation.md +++ b/packages/eslint-plugin/docs/rules/dot-notation.md @@ -73,3 +73,10 @@ x['hello'] = 123; ``` If the TypeScript compiler option `noPropertyAccessFromIndexSignature` is set to `true`, then the above code is always allowed, even if `allowIndexSignaturePropertyAccess` is `false`. + +## When Not To Use It + +If you specifically want to use both member access kinds for stylistic reasons, or don't wish to enforce one style over the other, you can avoid this rule. + +However, keep in mind that inconsistent style can harm readability in a project. +We recommend picking a single option for this rule that works best for your project. diff --git a/packages/eslint-plugin/docs/rules/explicit-function-return-type.md b/packages/eslint-plugin/docs/rules/explicit-function-return-type.md index 6aa1e6213145..ad6b5598e557 100644 --- a/packages/eslint-plugin/docs/rules/explicit-function-return-type.md +++ b/packages/eslint-plugin/docs/rules/explicit-function-return-type.md @@ -317,8 +317,7 @@ var bar = (function () { ## When Not To Use It -If you don't wish to prevent calling code from using function return values in unexpected ways, then -you will not need this rule. +If you don't find the added cost of explicitly writing function return types to be worth the visual clarity, or your project is not large enough for it to be a factor in type checking performance, then you will not need this rule. ## Further Reading diff --git a/packages/eslint-plugin/docs/rules/explicit-member-accessibility.md b/packages/eslint-plugin/docs/rules/explicit-member-accessibility.md index d41f85c09c40..83b183800d86 100644 --- a/packages/eslint-plugin/docs/rules/explicit-member-accessibility.md +++ b/packages/eslint-plugin/docs/rules/explicit-member-accessibility.md @@ -333,7 +333,11 @@ class Animal { ## When Not To Use It -If you think defaulting to public is a good default, then you should consider using the `no-public` setting. If you want to mix implicit and explicit public members then disable this rule. +If you think defaulting to public is a good default, then you should consider using the `no-public` setting. +If you want to mix implicit and explicit public members then you can disable this rule. + +However, keep in mind that inconsistent style can harm readability in a project. +We recommend picking a single option for this rule that works best for your project. ## Further Reading diff --git a/packages/eslint-plugin/docs/rules/explicit-module-boundary-types.md b/packages/eslint-plugin/docs/rules/explicit-module-boundary-types.md index 306c455c0041..d70bc3b17d81 100644 --- a/packages/eslint-plugin/docs/rules/explicit-module-boundary-types.md +++ b/packages/eslint-plugin/docs/rules/explicit-module-boundary-types.md @@ -243,8 +243,12 @@ export const foo: FooType = bar => {}; ## When Not To Use It -If you wish to make sure all functions have explicit return types, as opposed to only the module boundaries, you can use [explicit-function-return-type](./explicit-function-return-type.md) +If your project is not used by downstream consumers that are sensitive to API types, you can disable this rule. ## Further Reading - TypeScript [Functions](https://www.typescriptlang.org/docs/handbook/functions.html#function-types) + +## Related To + +- [explicit-function-return-type](./explicit-function-return-type.md) diff --git a/packages/eslint-plugin/docs/rules/member-delimiter-style.md b/packages/eslint-plugin/docs/rules/member-delimiter-style.md index d2e1f59ec4fc..6ac58c573cee 100644 --- a/packages/eslint-plugin/docs/rules/member-delimiter-style.md +++ b/packages/eslint-plugin/docs/rules/member-delimiter-style.md @@ -158,4 +158,7 @@ type FooBar = { name: string; greet(): string } ## When Not To Use It -If you don't care about enforcing a consistent member delimiter in interfaces and type literals, then you will not need this rule. +If you specifically want to use both member delimiter kinds for stylistic reasons, or don't wish to enforce one style over the other, you can avoid this rule. + +However, keep in mind that inconsistent style can harm readability in a project. +We recommend picking a single option for this rule that works best for your project. diff --git a/packages/eslint-plugin/docs/rules/method-signature-style.md b/packages/eslint-plugin/docs/rules/method-signature-style.md index a731e85bfacb..b834d383d649 100644 --- a/packages/eslint-plugin/docs/rules/method-signature-style.md +++ b/packages/eslint-plugin/docs/rules/method-signature-style.md @@ -108,3 +108,6 @@ type T2 = { ## When Not To Use It If you don't want to enforce a particular style for object/interface function types, and/or if you don't use `strictFunctionTypes`, then you don't need this rule. + +However, keep in mind that inconsistent style can harm readability in a project. +We recommend picking a single option for this rule that works best for your project. diff --git a/packages/eslint-plugin/docs/rules/naming-convention.md b/packages/eslint-plugin/docs/rules/naming-convention.md index ac8cf6d0bcbe..ba5a59adda96 100644 --- a/packages/eslint-plugin/docs/rules/naming-convention.md +++ b/packages/eslint-plugin/docs/rules/naming-convention.md @@ -711,4 +711,11 @@ You can use the `destructured` modifier to match these names, and explicitly set ## When Not To Use It -If you do not want to enforce naming conventions for anything. +This rule can be very strict. +If you don't have strong needs for enforcing naming conventions, we recommend using it only to flag very egregious violations of your naming standards. +Consider documenting your naming conventions and enforcing them in code review if you have processes like that. + +If you do not want to enforce naming conventions for anything, you can disable this rule. + +However, keep in mind that inconsistent style can harm readability in a project. +We recommend that if you care about naming conventions, pick a single option for this rule that works best for your project. diff --git a/packages/eslint-plugin/docs/rules/no-base-to-string.md b/packages/eslint-plugin/docs/rules/no-base-to-string.md index 4f7b230fe41f..470e49121c3a 100644 --- a/packages/eslint-plugin/docs/rules/no-base-to-string.md +++ b/packages/eslint-plugin/docs/rules/no-base-to-string.md @@ -76,7 +76,7 @@ let text = `${value}`; ## When Not To Use It -If you don't mind `"[object Object]"` in your strings, then you will not need this rule. +If you don't mind a risk of `"[object Object]"` or incorrect type coercions in your values, then you will not need this rule. ## Related To diff --git a/packages/eslint-plugin/docs/rules/no-confusing-void-expression.md b/packages/eslint-plugin/docs/rules/no-confusing-void-expression.md index 9e8acf5fb171..ef2b51b64724 100644 --- a/packages/eslint-plugin/docs/rules/no-confusing-void-expression.md +++ b/packages/eslint-plugin/docs/rules/no-confusing-void-expression.md @@ -113,4 +113,4 @@ console.log(void alert('Hello, world!')); The return type of a function can be inspected by going to its definition or hovering over it in an IDE. If you don't care about being explicit about the void type in actual code then don't use this rule. -Also, if you prefer concise coding style then also don't use it. +Also, if you strongly prefer a concise coding style more strongly than any fear of `void`-related bugs then you can avoid this rule. diff --git a/packages/eslint-plugin/docs/rules/no-duplicate-enum-values.md b/packages/eslint-plugin/docs/rules/no-duplicate-enum-values.md index 22b951a4a160..4e5488cdcba9 100644 --- a/packages/eslint-plugin/docs/rules/no-duplicate-enum-values.md +++ b/packages/eslint-plugin/docs/rules/no-duplicate-enum-values.md @@ -48,3 +48,11 @@ enum E { B = 'B', } ``` + +## When Not To Use It + +It can sometimes be useful to include duplicate enum members for very specific use cases. +For example, when renaming an enum member, it can sometimes be useful to keep the old name until a scheduled major breaking change. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. + +In general, if your project intentionally duplicates enum member values, you can avoid this rule. diff --git a/packages/eslint-plugin/docs/rules/no-duplicate-type-constituents.md b/packages/eslint-plugin/docs/rules/no-duplicate-type-constituents.md index c240bd4582eb..744537d0900e 100644 --- a/packages/eslint-plugin/docs/rules/no-duplicate-type-constituents.md +++ b/packages/eslint-plugin/docs/rules/no-duplicate-type-constituents.md @@ -57,3 +57,10 @@ When set to true, duplicate checks on intersection type constituents are ignored ### `ignoreUnions` When set to true, duplicate checks on union type constituents are ignored. + +## When Not To Use It + +It can sometimes be useful for the sake of documentation to include aliases for the same type. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. + +> In some of those cases, [branded types](https://basarat.gitbook.io/typescript/main-1/nominaltyping#using-interfaces) might be a type-safe way to represent the underlying data types. diff --git a/packages/eslint-plugin/docs/rules/no-dynamic-delete.md b/packages/eslint-plugin/docs/rules/no-dynamic-delete.md index e6afb335bc84..1fd8f9123455 100644 --- a/packages/eslint-plugin/docs/rules/no-dynamic-delete.md +++ b/packages/eslint-plugin/docs/rules/no-dynamic-delete.md @@ -47,7 +47,7 @@ delete container['-Infinity']; ## When Not To Use It When you know your keys are safe to delete, this rule can be unnecessary. -Some environments such as older browsers might not support `Map` and `Set`. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. Do not consider this rule as performance advice before profiling your code's bottlenecks. Even repeated minor performance slowdowns likely do not significantly affect your application's general perceived speed. diff --git a/packages/eslint-plugin/docs/rules/no-empty-function.md b/packages/eslint-plugin/docs/rules/no-empty-function.md index f650aa997eee..6275a1de7f77 100644 --- a/packages/eslint-plugin/docs/rules/no-empty-function.md +++ b/packages/eslint-plugin/docs/rules/no-empty-function.md @@ -84,3 +84,12 @@ class Foo extends Base { protected override greet(): void {} } ``` + +## When Not To Use It + +If you are working with external APIs that require functions even if they do nothing, then you may want to avoid this rule. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. + +Test code often violates this rule as well. +If your testing setup doesn't support "mock" or "spy" functions such as [`jest.fn()`](https://jestjs.io/docs/mock-functions), [`sinon.spy()`](https://sinonjs.org/releases/latest/spies), or [`vi.fn()`](https://vitest.dev/guide/mocking.html), you may wish to disable this rule in test files. +Again, if those cases aren't extremely common, you might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule in test files. diff --git a/packages/eslint-plugin/docs/rules/no-explicit-any.md b/packages/eslint-plugin/docs/rules/no-explicit-any.md index 5694ebf709a1..5e251fb7a03b 100644 --- a/packages/eslint-plugin/docs/rules/no-explicit-any.md +++ b/packages/eslint-plugin/docs/rules/no-explicit-any.md @@ -138,6 +138,8 @@ Most commonly: - If an external package doesn't yet have typings and you want to use `any` pending adding a `.d.ts` for it - You're working with particularly complex or nuanced code that can't yet be represented in the TypeScript type system +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. + ## Related To - [`no-unsafe-argument`](./no-unsafe-argument.md) @@ -148,5 +150,7 @@ Most commonly: ## Further Reading +- TypeScript [`any` type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#any) +- TypeScript's [`unknown` type](https://www.typescriptlang.org/docs/handbook/2/functions.html#unknown) - TypeScript [`any` type documentation](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#any) - TypeScript [`unknown` type release notes](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-0.html#new-unknown-top-type) diff --git a/packages/eslint-plugin/docs/rules/no-extra-non-null-assertion.md b/packages/eslint-plugin/docs/rules/no-extra-non-null-assertion.md index db2c584827c7..5e71dc011a70 100644 --- a/packages/eslint-plugin/docs/rules/no-extra-non-null-assertion.md +++ b/packages/eslint-plugin/docs/rules/no-extra-non-null-assertion.md @@ -50,3 +50,5 @@ function foo(bar?: { n: number }) { return bar?.n; } ``` + + diff --git a/packages/eslint-plugin/docs/rules/no-extraneous-class.md b/packages/eslint-plugin/docs/rules/no-extraneous-class.md index c0bd1de4ca75..451b01ae4a5d 100644 --- a/packages/eslint-plugin/docs/rules/no-extraneous-class.md +++ b/packages/eslint-plugin/docs/rules/no-extraneous-class.md @@ -291,4 +291,5 @@ class Constants { ## When Not To Use It -You can disable this rule if you are unable -or unwilling- to switch off using classes as namespaces. +If your project was set up before modern class and namespace practices, and you don't have the time to switch over, you might not be practically able to use this rule. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. diff --git a/packages/eslint-plugin/docs/rules/no-floating-promises.md b/packages/eslint-plugin/docs/rules/no-floating-promises.md index 69eca84b179b..c08216cd794e 100644 --- a/packages/eslint-plugin/docs/rules/no-floating-promises.md +++ b/packages/eslint-plugin/docs/rules/no-floating-promises.md @@ -99,7 +99,9 @@ await(async function () { ## When Not To Use It -If you do not use Promise-like values in your codebase, or want to allow them to remain unhandled. +This rule can be difficult to enable on large existing projects that set up many floating Promises. +Alternately, if you're not worried about crashes from floating or misused Promises -such as if you have global unhandled Promise handlers registered- then in some cases it may be safe to not use this rule. +You might consider using `void`s and/or [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. ## Related To diff --git a/packages/eslint-plugin/docs/rules/no-for-in-array.md b/packages/eslint-plugin/docs/rules/no-for-in-array.md index 759f427b9ace..2777c32a1e5d 100644 --- a/packages/eslint-plugin/docs/rules/no-for-in-array.md +++ b/packages/eslint-plugin/docs/rules/no-for-in-array.md @@ -53,4 +53,5 @@ for (const [i, value] of array.entries()) { ## When Not To Use It -If you want to iterate through a loop using the indices in an array as strings, you can turn off this rule. +If your project is a rare one that intentionally loops over string indices of arrays, you can turn off this rule. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. diff --git a/packages/eslint-plugin/docs/rules/no-implied-eval.md b/packages/eslint-plugin/docs/rules/no-implied-eval.md index 918b6a12e755..10f787d6d43f 100644 --- a/packages/eslint-plugin/docs/rules/no-implied-eval.md +++ b/packages/eslint-plugin/docs/rules/no-implied-eval.md @@ -98,4 +98,5 @@ setTimeout(Foo.fn, 100); ## When Not To Use It -If you want to allow `new Function()` or `setTimeout()`, `setInterval()`, `setImmediate()` and `execScript()` with string arguments, then you can safely disable this rule. +If your project is a rare one that needs to allow `new Function()` or `setTimeout()`, `setInterval()`, `setImmediate()` and `execScript()` with string arguments, then you can disable this rule. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. diff --git a/packages/eslint-plugin/docs/rules/no-import-type-side-effects.md b/packages/eslint-plugin/docs/rules/no-import-type-side-effects.md index 35b8f2c5282e..fedd08cb19f0 100644 --- a/packages/eslint-plugin/docs/rules/no-import-type-side-effects.md +++ b/packages/eslint-plugin/docs/rules/no-import-type-side-effects.md @@ -65,8 +65,7 @@ import T, { type U } from 'mod'; ## When Not To Use It -- If you want to leave behind side effect imports, then you shouldn't use this rule. -- If you're not using TypeScript 5.0's `verbatimModuleSyntax` option, then you don't need this rule. +If you're not using TypeScript 5.0's `verbatimModuleSyntax` option and your project is built with a bundler that manages import side effects for you, this rule may not be as useful for you. ## Related To diff --git a/packages/eslint-plugin/docs/rules/no-inferrable-types.md b/packages/eslint-plugin/docs/rules/no-inferrable-types.md index 2a06fa890f3c..721c6ce6c0c3 100644 --- a/packages/eslint-plugin/docs/rules/no-inferrable-types.md +++ b/packages/eslint-plugin/docs/rules/no-inferrable-types.md @@ -96,8 +96,8 @@ class Foo { ## When Not To Use It -If you do not want to enforce inferred types. +If you strongly prefer to have explicit types regardless of whether they can be inferred, this rule may not be for you. ## Further Reading -TypeScript [Inference](https://www.typescriptlang.org/docs/handbook/type-inference.html) +- [TpeScript Inference](https://www.typescriptlang.org/docs/handbook/type-inference.html) diff --git a/packages/eslint-plugin/docs/rules/no-invalid-void-type.md b/packages/eslint-plugin/docs/rules/no-invalid-void-type.md index eaa488116424..426e878c67d4 100644 --- a/packages/eslint-plugin/docs/rules/no-invalid-void-type.md +++ b/packages/eslint-plugin/docs/rules/no-invalid-void-type.md @@ -109,5 +109,4 @@ class Example { ## When Not To Use It -If you don't care about if `void` is used with other types, -or in invalid places, then you don't need this rule. +If you don't care about if `void` is used with other types, or in invalid places, then you don't need this rule. diff --git a/packages/eslint-plugin/docs/rules/no-magic-numbers.md b/packages/eslint-plugin/docs/rules/no-magic-numbers.md index fa2c7c167a25..211add8302a7 100644 --- a/packages/eslint-plugin/docs/rules/no-magic-numbers.md +++ b/packages/eslint-plugin/docs/rules/no-magic-numbers.md @@ -111,3 +111,9 @@ Examples of **correct** code for the `{ "ignoreTypeIndexes": true }` option: type Foo = Bar[0]; type Baz = Parameters[2]; ``` + +## When Not To Use It + +If your project frequently deals with constant numbers and you don't wish to take up extra space to declare them, this rule might not be for you. +We recommend at least using descriptive comments and/or names to describe constants. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) instead of completely disabling this rule. diff --git a/packages/eslint-plugin/docs/rules/no-meaningless-void-operator.md b/packages/eslint-plugin/docs/rules/no-meaningless-void-operator.md index f904c473d667..5c149ef653af 100644 --- a/packages/eslint-plugin/docs/rules/no-meaningless-void-operator.md +++ b/packages/eslint-plugin/docs/rules/no-meaningless-void-operator.md @@ -45,3 +45,7 @@ void bar(); // discarding a number ## Options `checkNever: true` will suggest removing `void` when the argument has type `never`. + +## When Not To Use It + +If you don't mind extra `void`s in your project, you can avoid this rule. diff --git a/packages/eslint-plugin/docs/rules/no-misused-new.md b/packages/eslint-plugin/docs/rules/no-misused-new.md index a311c40be7a0..b3fc829f42d8 100644 --- a/packages/eslint-plugin/docs/rules/no-misused-new.md +++ b/packages/eslint-plugin/docs/rules/no-misused-new.md @@ -43,4 +43,5 @@ interface I { ## When Not To Use It -If you intentionally want a class with a `new` method, and you're confident nobody working in your code will mistake it with a constructor. +If you intentionally want a class with a `new` method, and you're confident nobody working in your code will mistake it with a constructor, you might not want this rule. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. diff --git a/packages/eslint-plugin/docs/rules/no-misused-promises.md b/packages/eslint-plugin/docs/rules/no-misused-promises.md index b1cddcb6d68d..d8152f5d55fa 100644 --- a/packages/eslint-plugin/docs/rules/no-misused-promises.md +++ b/packages/eslint-plugin/docs/rules/no-misused-promises.md @@ -233,8 +233,9 @@ return { foo: 42, ...(await getData2()) }; ## When Not To Use It -If you do not use Promises in your codebase or are not concerned with possible -misuses of them outside of what the TypeScript compiler will check. +This rule can be difficult to enable on large existing projects that set up many misused Promises. +Alternately, if you're not worried about crashes from floating or misused Promises -such as if you have global unhandled Promise handlers registered- then in some cases it may be safe to not use this rule. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. ## Further Reading diff --git a/packages/eslint-plugin/docs/rules/no-namespace.md b/packages/eslint-plugin/docs/rules/no-namespace.md index 47e9670f572a..c5e77612aa3b 100644 --- a/packages/eslint-plugin/docs/rules/no-namespace.md +++ b/packages/eslint-plugin/docs/rules/no-namespace.md @@ -120,7 +120,9 @@ declare module 'foo' {} ## When Not To Use It -If you are using the ES2015 module syntax, then you will not need this rule. +If your project was architected before modern modules and namespaces, it may be difficult to migrate off of namespaces. +In that case you may not be able to use this rule for parts of your project. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. ## Further Reading diff --git a/packages/eslint-plugin/docs/rules/no-non-null-asserted-nullish-coalescing.md b/packages/eslint-plugin/docs/rules/no-non-null-asserted-nullish-coalescing.md index 09bf9be3be84..f7ac17e740d4 100644 --- a/packages/eslint-plugin/docs/rules/no-non-null-asserted-nullish-coalescing.md +++ b/packages/eslint-plugin/docs/rules/no-non-null-asserted-nullish-coalescing.md @@ -43,6 +43,11 @@ let x: string; x! ?? ''; ``` +## When Not To Use It + +If your project's types don't yet fully describe whether certain values may be nullable, such as if you're transitioning to `strictNullChecks`, this rule might create many false reports. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. + ## Further Reading - [TypeScript 3.7 Release Notes](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html) diff --git a/packages/eslint-plugin/docs/rules/no-non-null-asserted-optional-chain.md b/packages/eslint-plugin/docs/rules/no-non-null-asserted-optional-chain.md index 4a6c1607a947..f758fb2ba7e7 100644 --- a/packages/eslint-plugin/docs/rules/no-non-null-asserted-optional-chain.md +++ b/packages/eslint-plugin/docs/rules/no-non-null-asserted-optional-chain.md @@ -29,6 +29,11 @@ foo?.bar; foo?.bar(); ``` +## When Not To Use It + +If your project's types don't yet fully describe whether certain values may be nullable, such as if you're transitioning to `strictNullChecks`, this rule might create many false reports. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. + ## Further Reading - [TypeScript 3.7 Release Notes](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html) diff --git a/packages/eslint-plugin/docs/rules/no-non-null-assertion.md b/packages/eslint-plugin/docs/rules/no-non-null-assertion.md index 874e01605c8e..1a676212fd80 100644 --- a/packages/eslint-plugin/docs/rules/no-non-null-assertion.md +++ b/packages/eslint-plugin/docs/rules/no-non-null-assertion.md @@ -38,5 +38,5 @@ const includesBaz = example.property?.includes('baz') ?? false; ## When Not To Use It -If your project does not use the `strictNullChecks` compiler option, this rule is likely useless to you. -If your code is often wildly incorrect with respect to strict null-checking, your code may not yet be ready for this rule. +If your project's types don't yet fully describe whether certain values may be nullable, such as if you're transitioning to `strictNullChecks`, this rule might create many false reports. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. diff --git a/packages/eslint-plugin/docs/rules/no-redundant-type-constituents.md b/packages/eslint-plugin/docs/rules/no-redundant-type-constituents.md index 69cd6c83af03..a18b06b4f42b 100644 --- a/packages/eslint-plugin/docs/rules/no-redundant-type-constituents.md +++ b/packages/eslint-plugin/docs/rules/no-redundant-type-constituents.md @@ -70,6 +70,20 @@ type IntersectionStringLiteral = 'foo'; This rule plays it safe and only works with bottom types, top types, and comparing literal types to primitive types. +## When Not To Use It + +Some projects choose to occasionally intentionally include a redundant type constituent for documentation purposes. +For example, the following code includes `string` in a union even though the `unknown` makes it redundant: + +```ts +/** + * Normally a string name, but sometimes arbitrary unknown data. + */ +type NameOrOther = string | unknown; +``` + +If you strongly feel a preference for these unnecessary type constituents, this rule might not be for you. + ## Further Reading - [Union Types](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types) diff --git a/packages/eslint-plugin/docs/rules/no-require-imports.md b/packages/eslint-plugin/docs/rules/no-require-imports.md index 6e75a3d41cd3..746ca6dff7ed 100644 --- a/packages/eslint-plugin/docs/rules/no-require-imports.md +++ b/packages/eslint-plugin/docs/rules/no-require-imports.md @@ -30,7 +30,8 @@ import * as lib3 from 'lib3'; ## When Not To Use It -If you don't care about using newer module syntax, then you will not need this rule. +If your project frequently uses older CommonJS `require`s, then this rule might not be applicable to you. +If only a subset of your project uses `require`s then you might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. ## Related To diff --git a/packages/eslint-plugin/docs/rules/no-this-alias.md b/packages/eslint-plugin/docs/rules/no-this-alias.md index 640d5a6a2b54..e9be8a524e6d 100644 --- a/packages/eslint-plugin/docs/rules/no-this-alias.md +++ b/packages/eslint-plugin/docs/rules/no-this-alias.md @@ -35,4 +35,5 @@ setTimeout(() => { ## When Not To Use It -If you need to assign `this` to variables, you shouldn’t use this rule. +If your project is structured in a way that it needs to assign `this` to variables, this rule is likely not for you. +If only a subset of your project assigns `this` to variables then you might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. diff --git a/packages/eslint-plugin/docs/rules/no-throw-literal.md b/packages/eslint-plugin/docs/rules/no-throw-literal.md index f4d189067b96..2e488ed4eda8 100644 --- a/packages/eslint-plugin/docs/rules/no-throw-literal.md +++ b/packages/eslint-plugin/docs/rules/no-throw-literal.md @@ -109,3 +109,5 @@ const defaultOptions: Options = { allowThrowingUnknown: false, }; ``` + + diff --git a/packages/eslint-plugin/docs/rules/no-type-alias.md b/packages/eslint-plugin/docs/rules/no-type-alias.md index bb1428fbf8d0..527903e6a5cb 100644 --- a/packages/eslint-plugin/docs/rules/no-type-alias.md +++ b/packages/eslint-plugin/docs/rules/no-type-alias.md @@ -606,10 +606,7 @@ type Foo = Partial; type Foo = Omit; ``` -## When Not To Use It - -When you can't express some shape with an interface or you need to use a union, tuple type, -callback, etc. that would cause the code to be unreadable or impractical. + ## Further Reading diff --git a/packages/eslint-plugin/docs/rules/no-unnecessary-boolean-literal-compare.md b/packages/eslint-plugin/docs/rules/no-unnecessary-boolean-literal-compare.md index 3397a96082ec..09d85216ba69 100644 --- a/packages/eslint-plugin/docs/rules/no-unnecessary-boolean-literal-compare.md +++ b/packages/eslint-plugin/docs/rules/no-unnecessary-boolean-literal-compare.md @@ -126,7 +126,7 @@ if (!(someNullCondition ?? true)) { | `!(nullableBooleanVar === false)` | `nullableBooleanVar ?? true` | Only checked/fixed if the `allowComparingNullableBooleansToFalse` option is `false` | | `!(nullableBooleanVar !== false)` | `!(nullableBooleanVar ?? true)` | Only checked/fixed if the `allowComparingNullableBooleansToFalse` option is `false` | -## Not To Use It +## When Not To Use It Do not use this rule when `strictNullChecks` is disabled. ESLint is not able to distinguish between `false` and `undefined` or `null` values. diff --git a/packages/eslint-plugin/docs/rules/no-unnecessary-condition.md b/packages/eslint-plugin/docs/rules/no-unnecessary-condition.md index 26b7de35f7ae..7afa80861999 100644 --- a/packages/eslint-plugin/docs/rules/no-unnecessary-condition.md +++ b/packages/eslint-plugin/docs/rules/no-unnecessary-condition.md @@ -95,7 +95,8 @@ If for some reason you cannot turn on `strictNullChecks`, but still want to use ## When Not To Use It -The main downside to using this rule is the need for type information. +If your project is not accurately typed, such as if it's in the process of being converted to TypeScript or is susceptible to [trade-offs in control flow analysis](https://github.com/Microsoft/TypeScript/issues/9998), it may be difficult to enable this rule for particularly non-type-safe areas of code. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. This rule has a known edge case of triggering on conditions that were modified within function calls (as side effects). It is due to limitations of TypeScript's type narrowing. diff --git a/packages/eslint-plugin/docs/rules/no-unnecessary-qualifier.md b/packages/eslint-plugin/docs/rules/no-unnecessary-qualifier.md index 6ca2afe17f52..8c698145a93a 100644 --- a/packages/eslint-plugin/docs/rules/no-unnecessary-qualifier.md +++ b/packages/eslint-plugin/docs/rules/no-unnecessary-qualifier.md @@ -48,4 +48,4 @@ namespace A { ## When Not To Use It -If you don't care about having unneeded enum or namespace qualifiers, then you don't need to use this rule. +If you explicitly prefer to use fully qualified names, such as for explicitness, then you don't need to use this rule. diff --git a/packages/eslint-plugin/docs/rules/no-unnecessary-type-arguments.md b/packages/eslint-plugin/docs/rules/no-unnecessary-type-arguments.md index 43526aec5719..aa75e0359f4f 100644 --- a/packages/eslint-plugin/docs/rules/no-unnecessary-type-arguments.md +++ b/packages/eslint-plugin/docs/rules/no-unnecessary-type-arguments.md @@ -71,3 +71,7 @@ class D extends C {} interface I {} class Impl implements I {} ``` + +## When Not To Use It + +If you prefer explicitly specifying type parameters even when they are equal to the default, you can skip this rule. diff --git a/packages/eslint-plugin/docs/rules/no-unsafe-argument.md b/packages/eslint-plugin/docs/rules/no-unsafe-argument.md index a299b109603a..7605273f27ba 100644 --- a/packages/eslint-plugin/docs/rules/no-unsafe-argument.md +++ b/packages/eslint-plugin/docs/rules/no-unsafe-argument.md @@ -78,6 +78,16 @@ declare function foo(arg1: unknown, arg2: Set, arg3: unknown[]): void; foo(1 as any, new Set(), [] as any[]); ``` +## When Not To Use It + +If your codebase has many existing `any`s or areas of unsafe code, it may be difficult to enable this rule. +It may be easier to skip the `no-unsafe-*` rules pending increasing type safety in unsafe areas of your project. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. + ## Related To - [`no-explicit-any`](./no-explicit-any.md) +- [`no-unsafe-assignment`](./no-unsafe-assignment.md) +- [`no-unsafe-call`](./no-unsafe-call.md) +- [`no-unsafe-member-access`](./no-unsafe-member-access.md) +- [`no-unsafe-return`](./no-unsafe-return.md) diff --git a/packages/eslint-plugin/docs/rules/no-unsafe-assignment.md b/packages/eslint-plugin/docs/rules/no-unsafe-assignment.md index d5a216eff091..c506ea1bcba7 100644 --- a/packages/eslint-plugin/docs/rules/no-unsafe-assignment.md +++ b/packages/eslint-plugin/docs/rules/no-unsafe-assignment.md @@ -81,6 +81,16 @@ const x: unknown[] = y as any[]; const x: Set = y as Set; ``` +## When Not To Use It + +If your codebase has many existing `any`s or areas of unsafe code, it may be difficult to enable this rule. +It may be easier to skip the `no-unsafe-*` rules pending increasing type safety in unsafe areas of your project. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. + ## Related To - [`no-explicit-any`](./no-explicit-any.md) +- [`no-unsafe-argument`](./no-unsafe-argument.md) +- [`no-unsafe-call`](./no-unsafe-call.md) +- [`no-unsafe-member-access`](./no-unsafe-member-access.md) +- [`no-unsafe-return`](./no-unsafe-return.md) diff --git a/packages/eslint-plugin/docs/rules/no-unsafe-call.md b/packages/eslint-plugin/docs/rules/no-unsafe-call.md index 8fddb2774b61..140c92a5ed33 100644 --- a/packages/eslint-plugin/docs/rules/no-unsafe-call.md +++ b/packages/eslint-plugin/docs/rules/no-unsafe-call.md @@ -53,6 +53,16 @@ new Map(); String.raw`foo`; ``` +## When Not To Use It + +If your codebase has many existing `any`s or areas of unsafe code, it may be difficult to enable this rule. +It may be easier to skip the `no-unsafe-*` rules pending increasing type safety in unsafe areas of your project. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. + ## Related To - [`no-explicit-any`](./no-explicit-any.md) +- [`no-unsafe-argument`](./no-unsafe-argument.md) +- [`no-unsafe-assignment`](./no-unsafe-assignment.md) +- [`no-unsafe-member-access`](./no-unsafe-member-access.md) +- [`no-unsafe-return`](./no-unsafe-return.md) diff --git a/packages/eslint-plugin/docs/rules/no-unsafe-declaration-merging.md b/packages/eslint-plugin/docs/rules/no-unsafe-declaration-merging.md index 9c917aa3ee0c..441df05a2d47 100644 --- a/packages/eslint-plugin/docs/rules/no-unsafe-declaration-merging.md +++ b/packages/eslint-plugin/docs/rules/no-unsafe-declaration-merging.md @@ -49,6 +49,11 @@ namespace Qux {} function Qux() {} ``` +## When Not To Use It + +If your project intentionally defines classes and interfaces with unsafe declaration merging patterns, this rule might not be for you. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. + ## Further Reading - [Declaration Merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html) diff --git a/packages/eslint-plugin/docs/rules/no-unsafe-enum-comparison.md b/packages/eslint-plugin/docs/rules/no-unsafe-enum-comparison.md index 5db56d69b32d..008d355d4e2a 100644 --- a/packages/eslint-plugin/docs/rules/no-unsafe-enum-comparison.md +++ b/packages/eslint-plugin/docs/rules/no-unsafe-enum-comparison.md @@ -77,3 +77,6 @@ vegetable === Vegetable.Asparagus; ## When Not To Use It If you don't mind number and/or literal string constants being compared against enums, you likely don't need this rule. + +Separately, in the rare case of relying on an third party enums that are only imported as `type`s, it may be difficult to adhere to this rule. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. diff --git a/packages/eslint-plugin/docs/rules/no-unsafe-member-access.md b/packages/eslint-plugin/docs/rules/no-unsafe-member-access.md index 448ed7c9ee03..9ca36ee3566d 100644 --- a/packages/eslint-plugin/docs/rules/no-unsafe-member-access.md +++ b/packages/eslint-plugin/docs/rules/no-unsafe-member-access.md @@ -59,6 +59,16 @@ arr[idx]; arr[idx++]; ``` +## When Not To Use It + +If your codebase has many existing `any`s or areas of unsafe code, it may be difficult to enable this rule. +It may be easier to skip the `no-unsafe-*` rules pending increasing type safety in unsafe areas of your project. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. + ## Related To - [`no-explicit-any`](./no-explicit-any.md) +- [`no-unsafe-argument`](./no-unsafe-argument.md) +- [`no-unsafe-assignment`](./no-unsafe-assignment.md) +- [`no-unsafe-call`](./no-unsafe-call.md) +- [`no-unsafe-return`](./no-unsafe-return.md) diff --git a/packages/eslint-plugin/docs/rules/no-unsafe-return.md b/packages/eslint-plugin/docs/rules/no-unsafe-return.md index cb2d6f120f22..1137264d5f41 100644 --- a/packages/eslint-plugin/docs/rules/no-unsafe-return.md +++ b/packages/eslint-plugin/docs/rules/no-unsafe-return.md @@ -98,6 +98,16 @@ function foo2(): unknown[] { } ``` +## When Not To Use It + +If your codebase has many existing `any`s or areas of unsafe code, it may be difficult to enable this rule. +It may be easier to skip the `no-unsafe-*` rules pending increasing type safety in unsafe areas of your project. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. + ## Related To - [`no-explicit-any`](./no-explicit-any.md) +- [`no-unsafe-argument`](./no-unsafe-argument.md) +- [`no-unsafe-assignment`](./no-unsafe-assignment.md) +- [`no-unsafe-call`](./no-unsafe-call.md) +- [`no-unsafe-member-access`](./no-unsafe-member-access.md) diff --git a/packages/eslint-plugin/docs/rules/no-unsafe-unary-minus.md b/packages/eslint-plugin/docs/rules/no-unsafe-unary-minus.md index 94745d2c71c9..a215f8e19aa0 100644 --- a/packages/eslint-plugin/docs/rules/no-unsafe-unary-minus.md +++ b/packages/eslint-plugin/docs/rules/no-unsafe-unary-minus.md @@ -48,3 +48,5 @@ declare const d: any; declare const e: 1 | 2; -e; ``` + + diff --git a/packages/eslint-plugin/docs/rules/no-useless-empty-export.md b/packages/eslint-plugin/docs/rules/no-useless-empty-export.md index 9358e954b3ff..1720a223de56 100644 --- a/packages/eslint-plugin/docs/rules/no-useless-empty-export.md +++ b/packages/eslint-plugin/docs/rules/no-useless-empty-export.md @@ -41,3 +41,7 @@ export const value = 'Hello, world!'; ```ts import 'some-other-module'; ``` + +## When Not To Use It + +If you don't mind an empty `export {}` at the bottom of files, you likely don't need this rule. diff --git a/packages/eslint-plugin/docs/rules/no-var-requires.md b/packages/eslint-plugin/docs/rules/no-var-requires.md index 7230e4e8aebc..f4605ac335bd 100644 --- a/packages/eslint-plugin/docs/rules/no-var-requires.md +++ b/packages/eslint-plugin/docs/rules/no-var-requires.md @@ -30,7 +30,8 @@ import foo from 'foo'; ## When Not To Use It -If you don't care about using newer module syntax, then you will not need this rule. +If your project frequently uses older CommonJS `require`s, then this rule might not be applicable to you. +If only a subset of your project uses `require`s then you might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. ## Related To diff --git a/packages/eslint-plugin/docs/rules/non-nullable-type-assertion-style.md b/packages/eslint-plugin/docs/rules/non-nullable-type-assertion-style.md index 8f068f062e66..0dc6527ff0d3 100644 --- a/packages/eslint-plugin/docs/rules/non-nullable-type-assertion-style.md +++ b/packages/eslint-plugin/docs/rules/non-nullable-type-assertion-style.md @@ -38,4 +38,4 @@ const alsoDefinitely = maybe!; ## When Not To Use It -If you don't mind having unnecessarily verbose type casts, you can avoid this rule. +If you don't mind having unnecessarily verbose type assertions, you can avoid this rule. diff --git a/packages/eslint-plugin/docs/rules/parameter-properties.md b/packages/eslint-plugin/docs/rules/parameter-properties.md index 6d970076957c..830e2a5250bb 100644 --- a/packages/eslint-plugin/docs/rules/parameter-properties.md +++ b/packages/eslint-plugin/docs/rules/parameter-properties.md @@ -482,4 +482,7 @@ class Foo { ## When Not To Use It -If you don't care about the using parameter properties in constructors, then you will not need this rule. +If you don't care about which style of parameter properties in constructors is used in your classes, then you will not need this rule. + +However, keep in mind that inconsistent style can harm readability in a project. +We recommend picking a single option for this rule that works best for your project. diff --git a/packages/eslint-plugin/docs/rules/prefer-as-const.md b/packages/eslint-plugin/docs/rules/prefer-as-const.md index 628c573044cb..7bd979a84f72 100644 --- a/packages/eslint-plugin/docs/rules/prefer-as-const.md +++ b/packages/eslint-plugin/docs/rules/prefer-as-const.md @@ -41,4 +41,7 @@ let foo = { bar: 'baz' }; ## When Not To Use It -If you are using TypeScript < 3.4 +If you don't care about which style of literals assertions is used in your code, then you will not need this rule. + +However, keep in mind that inconsistent style can harm readability in a project. +We recommend picking a single option for this rule that works best for your project. diff --git a/packages/eslint-plugin/docs/rules/prefer-for-of.md b/packages/eslint-plugin/docs/rules/prefer-for-of.md index 83b7846acb0a..873d28bd7f0f 100644 --- a/packages/eslint-plugin/docs/rules/prefer-for-of.md +++ b/packages/eslint-plugin/docs/rules/prefer-for-of.md @@ -41,6 +41,4 @@ for (let i = 0; i < array.length; i++) { } ``` -## When Not To Use It - -If you transpile for browsers that do not support for-of loops, you may wish to use traditional for loops that produce more compact code. + diff --git a/packages/eslint-plugin/docs/rules/prefer-function-type.md b/packages/eslint-plugin/docs/rules/prefer-function-type.md index a8aca65f296b..c3e84ac491c1 100644 --- a/packages/eslint-plugin/docs/rules/prefer-function-type.md +++ b/packages/eslint-plugin/docs/rules/prefer-function-type.md @@ -84,7 +84,7 @@ type Intersection = ((data: string) => number) & ((id: number) => string); ## When Not To Use It -If you specifically want to use an interface or type literal with a single call signature for stylistic reasons, you can disable this rule. +If you specifically want to use an interface or type literal with a single call signature for stylistic reasons, you can avoid this rule. This rule has a known edge case of sometimes triggering on global augmentations such as `interface Function`. These edge cases are rare and often symptomatic of odd code. diff --git a/packages/eslint-plugin/docs/rules/prefer-includes.md b/packages/eslint-plugin/docs/rules/prefer-includes.md index 793014008beb..9a5db1fbf894 100644 --- a/packages/eslint-plugin/docs/rules/prefer-includes.md +++ b/packages/eslint-plugin/docs/rules/prefer-includes.md @@ -72,6 +72,4 @@ declare const mismatchExample: { mismatchExample.indexOf(value) >= 0; ``` -## When Not To Use It - -If you don't want to suggest `includes`, you can safely turn this rule off. + diff --git a/packages/eslint-plugin/docs/rules/prefer-literal-enum-member.md b/packages/eslint-plugin/docs/rules/prefer-literal-enum-member.md index ea276761c9ed..3684b84d5446 100644 --- a/packages/eslint-plugin/docs/rules/prefer-literal-enum-member.md +++ b/packages/eslint-plugin/docs/rules/prefer-literal-enum-member.md @@ -98,4 +98,4 @@ enum Foo { ## When Not To Use It -If you want use anything other than simple literals as an enum value. +If you want use anything other than simple literals as an enum value, this rule might not be for you. diff --git a/packages/eslint-plugin/docs/rules/prefer-namespace-keyword.md b/packages/eslint-plugin/docs/rules/prefer-namespace-keyword.md index f25b124c776a..97af2be93fa6 100644 --- a/packages/eslint-plugin/docs/rules/prefer-namespace-keyword.md +++ b/packages/eslint-plugin/docs/rules/prefer-namespace-keyword.md @@ -38,7 +38,7 @@ declare module 'foo' {} ## When Not To Use It -If you are using the ES2015 module syntax, then you will not need this rule. +If you are not using TypeScript's older `module`/`namespace` keywords, then you will not need this rule. ## Further Reading diff --git a/packages/eslint-plugin/docs/rules/prefer-optional-chain.md b/packages/eslint-plugin/docs/rules/prefer-optional-chain.md index 0c73e7d22c33..d09d5b046793 100644 --- a/packages/eslint-plugin/docs/rules/prefer-optional-chain.md +++ b/packages/eslint-plugin/docs/rules/prefer-optional-chain.md @@ -254,7 +254,8 @@ thing2 && thing2.toString(); ## When Not To Use It -If you don't mind using more explicit `&&`s/`||`s, you don't need this rule. +If your project is not accurately typed, such as if it's in the process of being converted to TypeScript or is susceptible to [trade-offs in control flow analysis](https://github.com/Microsoft/TypeScript/issues/9998), it may be difficult to enable this rule for particularly non-type-safe areas of code. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. ## Further Reading diff --git a/packages/eslint-plugin/docs/rules/prefer-readonly-parameter-types.md b/packages/eslint-plugin/docs/rules/prefer-readonly-parameter-types.md index 11b1b15503ee..0284cb96e436 100644 --- a/packages/eslint-plugin/docs/rules/prefer-readonly-parameter-types.md +++ b/packages/eslint-plugin/docs/rules/prefer-readonly-parameter-types.md @@ -380,3 +380,7 @@ type MyType = { }; function foo(arg: MyType) {} ``` + +## When Not To Use It + +If your project does not attempt to enforce strong immutability guarantees of parameters, you can avoid this rule. diff --git a/packages/eslint-plugin/docs/rules/prefer-readonly.md b/packages/eslint-plugin/docs/rules/prefer-readonly.md index 7018bca3fa23..3843ddbc7416 100644 --- a/packages/eslint-plugin/docs/rules/prefer-readonly.md +++ b/packages/eslint-plugin/docs/rules/prefer-readonly.md @@ -93,3 +93,7 @@ class Container { private neverModifiedPrivate = 'unchanged'; } ``` + +## When Not To Use It + +If you aren't trying to enforce strong immutability guarantees, this rule may be too restrictive for your project. diff --git a/packages/eslint-plugin/docs/rules/prefer-reduce-type-parameter.md b/packages/eslint-plugin/docs/rules/prefer-reduce-type-parameter.md index 520a25a653b5..5419248f8b5e 100644 --- a/packages/eslint-plugin/docs/rules/prefer-reduce-type-parameter.md +++ b/packages/eslint-plugin/docs/rules/prefer-reduce-type-parameter.md @@ -55,4 +55,6 @@ It will suggest instead pass the asserted type to `Array#reduce` as a generic ty ## When Not To Use It -If you don't want to use typechecking in your linting, you can't use this rule. +This rule can sometimes be difficult to work around when creating objects using a `.reduce`. +See [[prefer-reduce-type-parameter] unfixable reporting #3440](https://github.com/typescript-eslint/typescript-eslint/issues/3440) for more details. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. 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 573ce53ed09d..8b2f556ddf30 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 @@ -54,4 +54,5 @@ foo.endsWith('bar'); ## When Not To Use It -If you don't mind that style, you can turn this rule off safely. +If you don't mind which style of string checking is used, you can turn this rule off safely. +However, keep in mind that inconsistent style can harm readability in a project. diff --git a/packages/eslint-plugin/docs/rules/prefer-ts-expect-error.md b/packages/eslint-plugin/docs/rules/prefer-ts-expect-error.md index 8cc2abb23055..1eb824041fd3 100644 --- a/packages/eslint-plugin/docs/rules/prefer-ts-expect-error.md +++ b/packages/eslint-plugin/docs/rules/prefer-ts-expect-error.md @@ -63,6 +63,7 @@ const isOptionEnabled = (key: string): boolean => { ## When Not To Use It If you are compiling against multiple versions of TypeScript and using `@ts-ignore` to ignore version-specific type errors, this rule might get in your way. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. ## Further Reading diff --git a/packages/eslint-plugin/docs/rules/promise-function-async.md b/packages/eslint-plugin/docs/rules/promise-function-async.md index f3095ed1808c..a11dfdea3ce3 100644 --- a/packages/eslint-plugin/docs/rules/promise-function-async.md +++ b/packages/eslint-plugin/docs/rules/promise-function-async.md @@ -57,3 +57,8 @@ async function functionReturnsUnionWithPromiseImplicitly(p: boolean) { return p ? 'value' : Promise.resolve('value'); } ``` + +## When Not To Use It + +This rule can be difficult to enable on projects that use APIs which require functions to always be `async`. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) along with filing issues on your dependencies for those specific situations instead of completely disabling this rule. 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 4335d546cc3c..d97e78e9aa0a 100644 --- a/packages/eslint-plugin/docs/rules/require-array-sort-compare.md +++ b/packages/eslint-plugin/docs/rules/require-array-sort-compare.md @@ -75,4 +75,4 @@ const three = '3'; ## When Not To Use It -If you understand the language specification enough, and/or only ever sort arrays in a string-like manner, you can turn this rule off safely. +If you intentionally want your arrays to be always sorted in a string-like manner, you can turn this rule off safely. diff --git a/packages/eslint-plugin/docs/rules/restrict-plus-operands.md b/packages/eslint-plugin/docs/rules/restrict-plus-operands.md index e88e20644b8a..1a1c76495433 100644 --- a/packages/eslint-plugin/docs/rules/restrict-plus-operands.md +++ b/packages/eslint-plugin/docs/rules/restrict-plus-operands.md @@ -196,7 +196,7 @@ bar += 'test'; ## When Not To Use It -If you don't mind `"[object Object]"` in your strings, then you will not need this rule. +If you don't mind a risk of `"[object Object]"` or incorrect type coercions in your values, then you will not need this rule. ## Related To diff --git a/packages/eslint-plugin/docs/rules/restrict-template-expressions.md b/packages/eslint-plugin/docs/rules/restrict-template-expressions.md index 5124016b5307..e7e295c443a9 100644 --- a/packages/eslint-plugin/docs/rules/restrict-template-expressions.md +++ b/packages/eslint-plugin/docs/rules/restrict-template-expressions.md @@ -111,6 +111,10 @@ const arg = 'something'; const msg1 = typeof arg === 'string' ? arg : `arg = ${arg}`; ``` +## When Not To Use It + +If you're not worried about incorrectly stringifying non-string values in template literals, then you likely don't need this rule. + ## Related To - [`no-base-to-string`](./no-base-to-string.md) diff --git a/packages/eslint-plugin/docs/rules/sort-type-constituents.md b/packages/eslint-plugin/docs/rules/sort-type-constituents.md index 025e31ccad4f..c767bff5edd5 100644 --- a/packages/eslint-plugin/docs/rules/sort-type-constituents.md +++ b/packages/eslint-plugin/docs/rules/sort-type-constituents.md @@ -99,3 +99,9 @@ The ordering of groups is determined by this option. - `tuple` - Tuple types (`[A, B, C]`) - `union` - Union types (`A | B`) - `nullish` - `null` and `undefined` + +## When Not To Use It + +This rule is purely a stylistic rule for maintaining consistency in your project. +You can turn it off if you don't want to keep a consistent, predictable order for intersection and union types. +However, keep in mind that inconsistent style can harm readability in a project. diff --git a/packages/eslint-plugin/docs/rules/strict-boolean-expressions.md b/packages/eslint-plugin/docs/rules/strict-boolean-expressions.md index 45a7f8f94962..f0f702d03d51 100644 --- a/packages/eslint-plugin/docs/rules/strict-boolean-expressions.md +++ b/packages/eslint-plugin/docs/rules/strict-boolean-expressions.md @@ -178,6 +178,13 @@ This rule provides following fixes and suggestions for particular types in boole - `any` and `unknown` - Provides following suggestions: - Explicitly cast value to a boolean (`value` → `Boolean(value)`) +## When Not To Use It + +If your project isn't likely to experience bugs from falsy non-boolean values being used in logical conditions, you can skip enabling this rule. + +Otherwise, this rule can be quite strict around requiring exact comparisons in logical checks. +If you prefer more succinct checks over more precise boolean logic, this rule might not be for you. + ## Related To - [no-unnecessary-condition](./no-unnecessary-condition.md) - Similar rule which reports always-truthy and always-falsy values in conditions diff --git a/packages/eslint-plugin/docs/rules/switch-exhaustiveness-check.md b/packages/eslint-plugin/docs/rules/switch-exhaustiveness-check.md index 267a2199ed11..b362e97e1cf3 100644 --- a/packages/eslint-plugin/docs/rules/switch-exhaustiveness-check.md +++ b/packages/eslint-plugin/docs/rules/switch-exhaustiveness-check.md @@ -204,4 +204,4 @@ Since `value` is a non-union type it requires the switch case to have a default ## When Not To Use It -If you don't frequently `switch` over union types or enums with many parts, or intentionally wish to leave out some parts. +If you don't frequently `switch` over union types or enums with many parts, or intentionally wish to leave out some parts, this rule may not be for you. diff --git a/packages/eslint-plugin/docs/rules/triple-slash-reference.md b/packages/eslint-plugin/docs/rules/triple-slash-reference.md index 538c319059ed..40509d8fe235 100644 --- a/packages/eslint-plugin/docs/rules/triple-slash-reference.md +++ b/packages/eslint-plugin/docs/rules/triple-slash-reference.md @@ -50,9 +50,12 @@ import * as foo from 'foo'; import foo = require('foo'); ``` -## When To Use It +## When Not To Use It -If you want to ban use of one or all of the triple slash reference directives, or any time you might use triple-slash type reference directives and ES6 import declarations in the same file. +Most modern TypeScript projects generally use `import` statements to bring in types. +It's rare to need a `///` triple-slash reference outside of auto-generated code. +If your project is a rare one with one of those use cases, this rule might not be for you. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. ## When Not To Use It diff --git a/packages/eslint-plugin/docs/rules/unbound-method.md b/packages/eslint-plugin/docs/rules/unbound-method.md index f112947805d1..331394884211 100644 --- a/packages/eslint-plugin/docs/rules/unbound-method.md +++ b/packages/eslint-plugin/docs/rules/unbound-method.md @@ -98,6 +98,8 @@ log(); ## When Not To Use It -If your code intentionally waits to bind methods after use, such as by passing a `scope: this` along with the method, you can disable this rule. +If your project dynamically changes `this` scopes around in a way TypeScript has difficulties modeling, this rule may not be viable to use. +One likely difficult pattern is if your code intentionally waits to bind methods after use, such as by passing a `scope: this` along with the method. +You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. If you're wanting to use `toBeCalled` and similar matches in `jest` tests, you can disable this rule for your test files in favor of [`eslint-plugin-jest`'s version of this rule](https://github.com/jest-community/eslint-plugin-jest/blob/main/docs/rules/unbound-method.md). diff --git a/packages/eslint-plugin/docs/rules/unified-signatures.md b/packages/eslint-plugin/docs/rules/unified-signatures.md index 26f94da8c7f3..54f04d2385ec 100644 --- a/packages/eslint-plugin/docs/rules/unified-signatures.md +++ b/packages/eslint-plugin/docs/rules/unified-signatures.md @@ -66,3 +66,12 @@ function f(a: string): void; function f(a: number): void; function f(b: string): void; ``` + +## When Not To Use It + +This is purely a stylistic rule to help with readability of function signature overloads. +You can turn it off if you don't want to consistently keep them next to each other and unified. + +## Related To + +- [`adjacent-overload-signatures`](./adjacent-overload-signatures.md) diff --git a/packages/eslint-plugin/tests/docs.test.ts b/packages/eslint-plugin/tests/docs.test.ts index ce9f3115a02f..cc65cb32f4a7 100644 --- a/packages/eslint-plugin/tests/docs.test.ts +++ b/packages/eslint-plugin/tests/docs.test.ts @@ -8,13 +8,20 @@ import rules from '../src/rules'; const docsRoot = path.resolve(__dirname, '../docs/rules'); const rulesData = Object.entries(rules); -function parseMarkdownFile(filePath: string): marked.TokensList { - const file = fs.readFileSync(filePath, 'utf-8'); +interface ParsedMarkdownFile { + fullText: string; + tokens: marked.TokensList; +} + +function parseMarkdownFile(filePath: string): ParsedMarkdownFile { + const fullText = fs.readFileSync(filePath, 'utf-8'); - return marked.lexer(file, { + const tokens = marked.lexer(fullText, { gfm: true, silent: false, }); + + return { fullText, tokens }; } type TokenType = marked.Token['type']; @@ -63,7 +70,7 @@ describe('Validating rule docs', () => { describe(`${ruleName}.md`, () => { const filePath = path.join(docsRoot, `${ruleName}.md`); - const tokens = parseMarkdownFile(filePath); + const { fullText, tokens } = parseMarkdownFile(filePath); test(`${ruleName}.md must start with frontmatter description`, () => { expect(tokens[0]).toMatchObject({ @@ -91,31 +98,53 @@ describe('Validating rule docs', () => { }); }); - test(`headers must be title-cased`, () => { - // Get all H2 headers objects as the other levels are variable by design. - const headers = tokens.filter(tokenIsH2); + test(`headings must be title-cased`, () => { + // Get all H2 headings objects as the other levels are variable by design. + const headings = tokens.filter(tokenIsH2); - headers.forEach(header => - expect(header.text).toBe(titleCase(header.text)), + headings.forEach(heading => + expect(heading.text).toBe(titleCase(heading.text)), ); }); + const requiredHeadings = ['When Not To Use It']; const importantHeadings = new Set([ + ...requiredHeadings, 'How to Use', 'Options', 'Related To', - 'When Not To Use It', ]); test('important headings must be h2s', () => { - const headers = tokens.filter(tokenIsHeading); + const headings = tokens.filter(tokenIsHeading); - for (const header of headers) { - if (importantHeadings.has(header.raw.replace(/#/g, '').trim())) { - expect(header.depth).toBe(2); + for (const heading of headings) { + if (importantHeadings.has(heading.raw.replace(/#/g, '').trim())) { + expect(heading.depth).toBe(2); } } }); + + if (!rules[ruleName as keyof typeof rules].meta.docs?.extendsBaseRule) { + test('must include required headings', () => { + const headingTexts = new Set( + tokens.filter(tokenIsH2).map(token => token.text), + ); + + for (const requiredHeading of requiredHeadings) { + const omissionComment = ``; + + if ( + !headingTexts.has(requiredHeading) && + !fullText.includes(omissionComment) + ) { + throw new Error( + `Expected a '${requiredHeading}' heading or comment like ${omissionComment}.`, + ); + } + } + }); + } }); } });