diff --git a/.cspell.json b/.cspell.json index 4691cd152db3..0c5b1d6c2866 100644 --- a/.cspell.json +++ b/.cspell.json @@ -8,7 +8,7 @@ "**/*.{json,snap}", "**/**/CHANGELOG.md", "**/**/CONTRIBUTORS.md", - "**/**/ROADMAP.md", + "**/**/TSLINT_RULE_ALTERNATIVES.md", "**/coverage/**", "**/dist/**", "**/fixtures/**", @@ -59,6 +59,7 @@ "declarators", "destructure", "destructured", + "dprint", "errored", "erroring", "ESLint", @@ -88,6 +89,7 @@ "preact", "Premade", "prettier's", + "Quickstart", "recurse", "redeclaration", "redeclarations", diff --git a/.prettierignore b/.prettierignore index 913e2cce1e9f..97e17b8a77e1 100644 --- a/.prettierignore +++ b/.prettierignore @@ -17,6 +17,8 @@ packages/ast-spec/src/*/*/fixtures/_error_/*/fixture.ts # Syntax not yet supported packages/scope-manager/tests/fixtures/type-declaration/type-query-with-parameters.ts packages/scope-manager/tests/fixtures/type-declaration/infer-type-constraint.ts +packages/scope-manager/tests/fixtures/instantiation-expressions/type-arguments1.ts +packages/scope-manager/tests/fixtures/instantiation-expressions/type-arguments2.ts # Ignore CHANGELOG.md files to avoid issues with automated release job CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 795d6bba1762..f69637a73d7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,24 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.31.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.30.7...v5.31.0) (2022-07-25) + + +### Bug Fixes + +* **eslint-plugin:** [typedef] Support nested array destructuring with type annotation ([#5311](https://github.com/typescript-eslint/typescript-eslint/issues/5311)) ([6d19efe](https://github.com/typescript-eslint/typescript-eslint/commit/6d19efed16d1cf0357ad363b6373d2021c49a8c8)) +* **scope-manager:** handle typeParameters of TSInstantiationExpression ([#5355](https://github.com/typescript-eslint/typescript-eslint/issues/5355)) ([2595ccf](https://github.com/typescript-eslint/typescript-eslint/commit/2595ccf67cd5158edbd6bebd9ac2dbd8bbd8b99c)) + + +### Features + +* **eslint-plugin:** [consistent-generic-ctors] check class field declaration ([#5288](https://github.com/typescript-eslint/typescript-eslint/issues/5288)) ([48f996e](https://github.com/typescript-eslint/typescript-eslint/commit/48f996e8dda79c9c865e8ca6552069902836648b)) +* **eslint-plugin:** [prefer-nullish-coalescing] add ignoreTernaryTests option ([#4965](https://github.com/typescript-eslint/typescript-eslint/issues/4965)) ([f82727f](https://github.com/typescript-eslint/typescript-eslint/commit/f82727ffeb97475c07773ca1d1e5b9609fcc5e68)) + + + + + ## [5.30.7](https://github.com/typescript-eslint/typescript-eslint/compare/v5.30.6...v5.30.7) (2022-07-18) diff --git a/_redirects b/_redirects new file mode 100644 index 000000000000..1b61a020ea0e --- /dev/null +++ b/_redirects @@ -0,0 +1,4 @@ +/docs/linting /docs +/docs/linting/type-linting /docs/linting/typed-linting +/docs/linting/monorepo /docs/linting/typed-linting/monorepos +/docs/linting/tslint /docs/linting/troubleshooting/tslint diff --git a/docs/README.md b/docs/README.md index dfac81e925a2..23cbcd84ffa8 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,13 +1,79 @@ --- +id: getting-started title: Getting Started -sidebar_label: Getting Started slug: / --- -These docs will give you a quick overview of the project and all of its pieces, as well as provide guides to help you get set up. +## Quickstart -The docs are broken down into the following categories: +These steps will get you running ESLint with our recommended rules on your TypeScript code as quickly as possible. -- [I want to lint my TypeScript codebase.](./linting/README.md) +### Step 1: Installation -- [I want to develop an ESLint plugin in TypeScript.](./development/CUSTOM_RULES.md) +First, install the required packages for [ESLint](https://eslint.io), [TypeScript](https://typescriptlang.org), and this plugin: + +```bash npm2yarn +npm install --save-dev @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint typescript +``` + +### Step 2: Configuration + +Next, create a `.eslintrc.cjs` config file in the root of your project, and populate it with the following: + +```js title=".eslintrc.cjs" +module.exports = { + extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'], + parser: '@typescript-eslint/parser', + plugins: ['@typescript-eslint'], + root: true, +}; +``` + +:::info +If your project doesn't use ESM, naming the file as `.eslintrc.js` is fine. See [ESLint's Configuration Files docs](https://eslint.org/docs/user-guide/configuring/configuration-files) for more info. +::: + +### Step 3: Running ESLint + +Open a terminal to the root of your project and run the following command: + + + + +```bash +npx eslint . +``` + + + + +```bash +yarn eslint . +``` + + + + +ESLint will lint all TypeScript compatible files within the current folder, and will output the results to your terminal. + +## Details + +- You can read more about configuring ESLint [in their documentation on configuration](https://eslint.org/docs/user-guide/configuring). +- You can read more about the rules provided by ESLint [in their documentation on their rules](https://eslint.org/docs/rules/). +- You can read more about the rules provided by typescript-eslint in [our rules documentation](/rules). + +### Configuration Values + +- `parser: '@typescript-eslint/parser'` tells ESLint to use the [`@typescript-eslint/parser`](https://github.com/typescript-eslint/typescript-eslint/tree/main/packages/parser) package you installed to parse your source files. + - This is required, or else ESLint will throw errors as it tries to parse TypeScript code as if it were regular JavaScript. +- `plugins: ['@typescript-eslint']` tells ESLint to load the [`@typescript-eslint/eslint-plugin`](https://github.com/typescript-eslint/typescript-eslint/tree/main/packages/eslint-plugin) package as a plugin. + - This allows you to use typescript-eslint's rules within your codebase. +- `extends: [ ... ]` tells ESLint that your config extends the given configurations. + - `eslint:recommended` is ESLint's inbuilt "recommended" config - it turns on a small, sensible set of rules which lint for well-known best-practices. + - `plugin:@typescript-eslint/recommended` is our "recommended" config - it's just like `eslint:recommended`, except it only turns on rules from our TypeScript-specific plugin. + +## Next Steps + +We provide a plethora of powerful rules that utilize the power of TypeScript's type information. [Visit the next page for a setup guide](./linting/TYPED_LINTING.md 'Visit the next page for a typed rules setup guide'). + +If you're having problems getting this working, please have a look at our [Troubleshooting & FAQs](./linting/TROUBLESHOOTING.md). diff --git a/docs/development/architecture/PACKAGES.md b/docs/development/architecture/PACKAGES.md index 461cc0218120..f798e35b2e47 100644 --- a/docs/development/architecture/PACKAGES.md +++ b/docs/development/architecture/PACKAGES.md @@ -66,7 +66,7 @@ Any custom rules you write generally will be as well. [`@typescript-eslint/eslint-plugin-tslint`] is a separate ESLint plugin that allows running TSLint rules within ESLint to help you migrate from TSLint to ESLint. :::caution -**TSLint is deprecated.** It is in your best interest to migrate off it entirely. See [Linting > TSLint](../../linting/TSLINT.md). +**TSLint is deprecated.** It is in your best interest to migrate off it. See [Linting > Troubleshooting & FAQs > What About TSLint?](../../linting/troubleshooting/TSLINT.md). ::: [`@typescript-eslint/eslint-plugin-tslint`]: https://github.com/typescript-eslint/typescript-eslint/tree/main/packages/eslint-plugin-tslint diff --git a/docs/linting/CONFIGS.md b/docs/linting/CONFIGURATIONS.md similarity index 61% rename from docs/linting/CONFIGS.md rename to docs/linting/CONFIGURATIONS.md index 659064c69017..de05a216ff87 100644 --- a/docs/linting/CONFIGS.md +++ b/docs/linting/CONFIGURATIONS.md @@ -1,9 +1,10 @@ --- id: configs -sidebar_label: Configurations title: Configurations --- +[ESLint shareable configurations](https://eslint.org/docs/latest/developer-guide/shareable-configs) exist to provide a comprehensive base config for you, with the intention that you add the config and it gives you an opinionated setup. + ## Built-In Configurations `@typescript-eslint/eslint-plugin` includes built-in configurations you can extend from to pull in the recommended starting rules. @@ -11,6 +12,10 @@ title: Configurations With the exception of `strict`, all configurations are considered "stable". Rule additions and removals are treated as breaking changes and will only be done in major version bumps. +:::note +We recommend most packages extend from [`recommended-requiring-type-checking`](#recommended-requiring-type-checking) (which requires [typed linting](./TYPED_LINTING.md)). +::: + ### `eslint-recommended` This ruleset is meant to be used after extending `eslint:recommended`. @@ -60,7 +65,7 @@ Rules in this configuration are similarly useful to those in `recommended`. :::tip We recommend all TypeScript projects extend from this configuration, with the caveat that rules using type information take longer to run. -See [Linting with Type Information](/docs/linting/type-linting) for more details. +See [Linting with Type Information](/docs/linting/typed-linting) for more details. ::: ### `strict` @@ -89,4 +94,29 @@ See [ESLint's Configuring Rules docs](https://eslint.org/docs/user-guide/configu ### Suggesting Configuration Changes -If you feel strongly that a specific rule should (or should not) be one of these configurations, please feel free to [file an issue](https://github.com/typescript-eslint/typescript-eslint/issues/new/choose) along with a **detailed** argument explaining your reasoning. +If you feel strongly that a specific rule should (or should not) be one of these configurations, please [file an issue](https://github.com/typescript-eslint/typescript-eslint/issues/new?assignees=&labels=package%3A+eslint-plugin%2Cpreset+config+change%2Ctriage&template=09-config-change.yaml&title=Configs%3A+%3Ca+short+description+of+my+proposal%3E) along with a **detailed** argument explaining your reasoning. + +## Prettier + +If you use [`prettier`](https://www.npmjs.com/package/prettier), there is also a helpful config to help ensure ESLint doesn't report on formatting issues that prettier will fix: [`eslint-config-prettier`](https://www.npmjs.com/package/eslint-config-prettier). + +Using this config by adding it to the end of your `extends`: + +```js title=".eslintrc.js" +module.exports = { + root: true, + parser: '@typescript-eslint/parser', + plugins: ['@typescript-eslint'], + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + // Add this line + 'prettier', + ], +}; +``` + +:::warning +**We strongly recommend you use Prettier or an equivalent**, not ESLint formatting rules. +See [this issue](https://github.com/typescript-eslint/typescript-eslint/issues/4907 'Issue: Docs: Add our opinion on delegating stylistic issues to a tool such as Prettier #4907') for more information. +::: diff --git a/docs/linting/MONOREPO.md b/docs/linting/MONOREPO.md deleted file mode 100644 index 4ec2df161362..000000000000 --- a/docs/linting/MONOREPO.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -id: monorepo -title: Monorepo Configuration -sidebar_label: Monorepo Configuration ---- - -If you're using a monorepo, these docs will help you figure out how to setup typed linting. -If you don't want to use typed linting, then you can stop here - you don't need to do anything special. - -The first question to answer is how are your `tsconfig.json` setup? You should have one of two setups: - -1. One `tsconfig.json` per package (and an optional one in the root) -2. One root `tsconfig.json` - -## One `tsconfig.json` per package (and an optional one in the root) - -Earlier in our docs on [typed linting](./TYPED_LINTING.md), we showed you how to setup a config for typed linting using the `parserOptions.project` option. This option accepts an array of relative paths, allowing you to specify each and every `tsconfig.json` in your monorepo. For those of you with too many packages, you can also supply a [glob path](https://github.com/isaacs/node-glob/blob/f5a57d3d6e19b324522a3fa5bdd5075fd1aa79d1/README.md#glob-primer). - -For example, this is how we specify all of our `tsconfig.json` within this repo. - -```js title=".eslintrc.js" -module.exports = { - root: true, - parser: '@typescript-eslint/parser', - parserOptions: { - tsconfigRootDir: __dirname, - // Remove this line - project: ['./tsconfig.json'], - // Add this line - project: ['./tsconfig.eslint.json', './packages/*/tsconfig.json'], - }, - plugins: ['@typescript-eslint'], - extends: [ - 'eslint:recommended', - 'plugin:@typescript-eslint/recommended', - 'plugin:@typescript-eslint/recommended-requiring-type-checking', - ], -}; -``` - -If you're looking for an example of what the `.eslintrc.js`, and referenced `tsconfig.json` might look like in a real example, look no further than this very repo. We're a multi-package monorepo that uses one `tsconfig.json` per package, that also uses typed linting. - -### Important note regarding large (> 10) multi-package monorepos - -We've had reports that for sufficiently large and/or interdependent projects, you may run into OOMs using this approach. Our advice is to set it up and test first, as there are very few cases that trigger this OOM. We are in the process of investigating solutions with the help of the TypeScript team. - -See [#1192](https://github.com/typescript-eslint/typescript-eslint/issues/1192) for more information and discussion. - -If you do run into an OOM, please comment on the above issue and let us know about your repo - the more information we have, the better. As an interim workaround, consider one of the following: - -- Switching to one root `tsconfig.eslint.json` (see below) -- Using a shell script to only lint one package at a time, using your existing config above. - -## One root `tsconfig.json` - -If you've only got one, you should inspect the `include` paths. If it doesn't include all of your files, then we won't be able to lint them. In this instance, you have two options: add them in to the `include`, or create a new config. - -The former doesn't always work for everyone if they've got a complex build, as adding more paths (like test paths) to `include` could break the build. -In those cases we suggest creating a new config called `tsconfig.eslint.json`, that looks something like this: - -```jsonc title="tsconfig.eslint.json" -{ - // extend your base config to share compilerOptions, etc - "extends": "./tsconfig.json", - "compilerOptions": { - // ensure that nobody can accidentally use this config for a build - "noEmit": true - }, - "include": [ - // whatever paths you intend to lint - "src", - "test", - "tools" - ] -} -``` - -Ensure you update your `.eslintrc.js` to point at this new config file. - -## Troubleshooting - -If you're having problems getting this working, please have a look at our [Troubleshooting FAQ](./TROUBLESHOOTING.md). diff --git a/docs/linting/README.md b/docs/linting/README.md deleted file mode 100644 index 23f0a2b1981a..000000000000 --- a/docs/linting/README.md +++ /dev/null @@ -1,223 +0,0 @@ ---- -id: linting -title: Linting your TypeScript Codebase -sidebar_label: Linting your TypeScript Codebase ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; - -Whether you're adding linting to a new TypeScript codebase, adding TypeScript to an old codebase, or migrating from the deprecated [TSLint](https://www.npmjs.com/package/tslint), the steps aren't a whole lot different. - -## Installation - -First step is to make sure you've got the required packages installed: - -```bash npm2yarn -npm install --save-dev eslint typescript @typescript-eslint/parser @typescript-eslint/eslint-plugin -``` - -## Configuration - -Next, create a `.eslintrc.cjs` config file in the root of your project, and populate it with the following: - - -```js title=".eslintrc.cjs" -module.exports = { - root: true, - parser: '@typescript-eslint/parser', - plugins: [ - '@typescript-eslint', - ], - extends: [ - 'eslint:recommended', - 'plugin:@typescript-eslint/recommended', - ], -}; -``` - -This is about the smallest config file we recommend. There's a lot more you can add to this as you further onboard, but this will be enough to get you started. - -:::info - -The `.cjs` extension will explicitly set the file to a [CommonJS module](https://nodejs.org/dist/latest-v18.x/docs/api/modules.html), in case your project has `"type": "module"` in its package.json. - -If your project doesn't use ESM, naming the file as `.eslintrc.js` is fine. See [ESLint's Configuration Files docs](https://eslint.org/docs/user-guide/configuring/configuration-files) for more info. - -::: - -### Details - -Explaining the important bits: - -- `parser: '@typescript-eslint/parser'` tells ESLint to use the parser package you installed ([`@typescript-eslint/parser`](https://github.com/typescript-eslint/typescript-eslint/tree/main/packages/parser)). - - This allows ESLint to understand TypeScript syntax. - - This is required, or else ESLint will throw errors as it tries to parse TypeScript code as if it were regular JavaScript. -- `plugins: ['@typescript-eslint']` tells ESLint to load the plugin package you installed ([`@typescript-eslint/eslint-plugin`](https://github.com/typescript-eslint/typescript-eslint/tree/main/packages/eslint-plugin)). - - This allows you to use the rules within your codebase. -- `extends: [ ... ]` tells ESLint that your config extends the given configurations. - - `eslint:recommended` is ESLint's inbuilt "recommended" config - it turns on a small, sensible set of rules which lint for well-known best-practices. - - `plugin:@typescript-eslint/recommended` is our "recommended" config - it's just like `eslint:recommended`, except it only turns on rules from our TypeScript-specific plugin. - -### Ignoring unnecessary files - -Next, create a `.eslintignore` file in the root of your project. -This file will tell ESLint which files and folders it should never lint. - -Add the following lines to the file: - -```ignore title=".eslintignore" -# don't lint build output (make sure it's set to your correct build folder name) -dist -``` - -### Further Configuration Documentation - -- You can read more about configuring ESLint [in their documentation on configuration](https://eslint.org/docs/user-guide/configuring). -- You can read more about the rules provided by ESLint [in their documentation on their rules](https://eslint.org/docs/rules/). -- You can read more about the rules provided by us in [our plugin documentation](https://typescript-eslint.io/rules/). - -## Running ESLint - -With that configured, open a terminal to the root of your project, and run the following command: - - - - -```bash -npx eslint . -``` - - - - -```bash -yarn eslint . -``` - - - - -That's it - ESLint will lint all TypeScript compatible files within the current folder, and will output the results to your terminal. - -You are also recommended to add an npm script in your package.json, so you don't have to repeat the same command every time you run ESLint. - -```json title="package.json" -{ - "scripts": { - "lint": "eslint ." - } -} -``` - -This way, you can invoke the `lint` script directly: - -```bash npm2yarn -npm run lint -``` - -:::note -If you use non-standard file extensions, you will need to explicitly tell ESLint to lint those extensions using the [`--ext` flag](https://eslint.org/docs/user-guide/command-line-interface#--ext) -::: - -You can also get results in realtime inside most IDEs via a plugin - search your IDE's extension store. - -## Next Steps - -With that configured you can now start to delve into the wide and extensive ESLint ecosystem of plugins and configs. - -### Type-Aware Rules - -We have a lot of awesome rules which utilize the power of TypeScript's type information. They require a little bit of extra setup beyond this first step, [so visit the next page to see how to set this up.](./TYPED_LINTING.md) - -### Prettier - -If you use [`prettier`](https://www.npmjs.com/package/prettier), there is also a helpful config to help ensure ESLint doesn't report on formatting issues that prettier will fix: [`eslint-config-prettier`](https://www.npmjs.com/package/eslint-config-prettier). - -Using this config by adding it to the end of your `extends`: - -```js title=".eslintrc.js" -module.exports = { - root: true, - parser: '@typescript-eslint/parser', - plugins: ['@typescript-eslint'], - extends: [ - 'eslint:recommended', - 'plugin:@typescript-eslint/recommended', - // Add this line - 'prettier', - ], -}; -``` - -### Community Configs - -Configurations exist solely to provide a comprehensive base config for you, with the intention that you add the config and it gives you an opinionated setup. -Many configuration packages exist in the ESLint ecosystem. -A few popular all-in-one configs are: - -- Airbnb's ESLint config: [`eslint-config-airbnb-typescript`](https://www.npmjs.com/package/eslint-config-airbnb-typescript). -- Standard: [`eslint-config-standard-with-typescript`](https://www.npmjs.com/package/eslint-config-standard-with-typescript). - -To use one of these complete config packages, you would replace the `extends` with the package name. -For example: - -```js title=".eslintrc.js" -module.exports = { - root: true, - parser: '@typescript-eslint/parser', - plugins: ['@typescript-eslint'], - extends: [ - // Removed lines start - 'eslint:recommended', - 'plugin:@typescript-eslint/recommended', - // Removed lines end - // Add this line - 'airbnb-typescript', - ], -}; -``` - - - -Search ["eslint-config" on npm](https://www.npmjs.com/search?q=eslint-config) for more. - -### Plugins - -ESLint plugins provide additional rules and other functionality on top of ESLint. -Below are just a few examples: - -- ESLint comment restrictions: [`eslint-plugin-eslint-comments`](https://www.npmjs.com/package/eslint-plugin-eslint-comments) -- Import/export conventions : [`eslint-plugin-import`](https://www.npmjs.com/package/eslint-plugin-import) -- Jest testing: [`eslint-plugin-jest`](https://www.npmjs.com/package/eslint-plugin-jest) -- NodeJS best practices: [`eslint-plugin-node`](https://www.npmjs.com/package/eslint-plugin-node) -- React best practices: [`eslint-plugin-react`](https://www.npmjs.com/package/eslint-plugin-react) and [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks) - -Every plugin that is out there includes documentation on the various configurations and rules they offer. -A typical plugin might be used like: - -```js title=".eslintrc.js" -module.exports = { - root: true, - parser: '@typescript-eslint/parser', - plugins: [ - '@typescript-eslint', - // Add this line - 'jest', - ], - extends: [ - 'eslint:recommended', - 'plugin:@typescript-eslint/recommended', - // Add this line - 'plugin:jest/recommended', - ], -}; -``` - - - -Search ["eslint-plugin" on npm](https://www.npmjs.com/search?q=eslint-plugin) for more. - -## Troubleshooting - -If you're having problems getting this working, please have a look at our [Troubleshooting FAQ](./TROUBLESHOOTING.md). diff --git a/docs/linting/TROUBLESHOOTING.md b/docs/linting/TROUBLESHOOTING.md index d9c447b4d0e2..f37f8780a332 100644 --- a/docs/linting/TROUBLESHOOTING.md +++ b/docs/linting/TROUBLESHOOTING.md @@ -1,7 +1,6 @@ --- id: troubleshooting title: Troubleshooting & FAQs -sidebar_label: Troubleshooting & FAQs --- ## I am using a rule from ESLint core, and it doesn't work correctly with TypeScript code @@ -31,12 +30,10 @@ If you don't find an existing extension rule, or the extension rule doesn't work ## I get errors telling me "The file must be included in at least one of the projects provided" -This error means that the file that's being linted is not included in any of the tsconfig files you provided us. +This error means that the file that's being linted is not included in any of the TSConfig files you provided us. This happens when users have test files, config files, or similar that are not included. -There are a couple of solutions to this, depending on what you want to achieve. - -See our docs on [type aware linting](./TYPED_LINTING.md#i-get-errors-telling-me-the-file-must-be-included-in-at-least-one-of-the-projects-provided) for solutions to this. +See our docs on [type aware linting](./TYPED_LINTING.md#i-get-errors-telling-me-the-file-must-be-included-in-at-least-one-of-the-projects-provided) for solutions. ## I use a framework (like Vue) that requires custom file extensions, and I get errors like "You should add `parserOptions.extraFileExtensions` to your config" diff --git a/docs/linting/TYPED_LINTING.md b/docs/linting/TYPED_LINTING.md index ae58028e442b..7a037e9a178b 100644 --- a/docs/linting/TYPED_LINTING.md +++ b/docs/linting/TYPED_LINTING.md @@ -1,11 +1,9 @@ --- -id: type-linting +id: typed-linting title: Linting with Type Information -sidebar_label: Linting with Type Information --- -Under the hood, the typescript-eslint parser uses TypeScript's compiler APIs to parse the files. This means that we can provide lint rules with access to all of the type information that TypeScript knows about your codebase. - +Some typescript-eslint rules tap utilize the awesome power of TypeScript's type checking APIs to provide much deeper insights into your code. To tap into TypeScript's additional powers, there are two small changes you need to make to your config file: ```js title=".eslintrc.js" @@ -32,22 +30,23 @@ In more detail: - `parserOptions.tsconfigRootDir` tells our parser the absolute path of your project's root directory. - `parserOptions.project` tells our parser the relative path where your project's `tsconfig.json` is. - - If your project is a multi-package monorepo, see [our docs on configuring a monorepo](./MONOREPO.md). + - If your project is a multi-package monorepo, see [our docs on configuring a monorepo](./typed-linting/MONOREPOS.md). - `plugin:@typescript-eslint/recommended-requiring-type-checking` is another recommended configuration we provide. This one contains rules that specifically require type information. With that done, run the same lint command you ran before. -You will see new rules reporting errors based on type information! +You may see new rules reporting errors based on type information! ## FAQs ### How is performance? -_But wait_ - I hear you exclaim - _why would you ever not want type-aware rules?_ - -Well (for full disclosure) there is a catch; by including `parserOptions.project` in your config, you are essentially asking TypeScript to do a build of your project before ESLint can do its linting. For small projects this takes a negligible amount of time (a few seconds); for large projects, it can take longer (30s or more). +Typed rules come with a catch. +By including `parserOptions.project` in your config, you incur the performance penalty of asking TypeScript to do a build of your project before ESLint can do its linting. +For small projects this takes a negligible amount of time (a few seconds or less); for large projects, it can take longer. -Most of our users are fine with this, as they think the power of type-aware static analysis is worth it. -Additionally, most users primarily consume lint errors via IDE plugins which, through some caching magic, do not suffer the same penalties. This means that generally they usually only run a complete lint before a push, or via their CI, where the extra time really doesn't matter. +Most of our users do not mind this cost as the power and safety of type-aware static analysis rules is worth the tradeoff. +Additionally, most users primarily consume lint errors via IDE plugins which, through caching, do not suffer the same penalties. +This means that generally they usually only run a complete lint before a push, or via their CI, where the extra time often doesn't matter. **We strongly recommend you do use type-aware linting**, but the above information is included so that you can make your own, informed decision. diff --git a/docs/linting/troubleshooting/FORMATTING.md b/docs/linting/troubleshooting/FORMATTING.md new file mode 100644 index 000000000000..d39fdd568246 --- /dev/null +++ b/docs/linting/troubleshooting/FORMATTING.md @@ -0,0 +1,34 @@ +--- +id: formatting +title: What About Formatting? +--- + +We strongly recommend against using ESLint for formatting. +We strongly recommend using [Prettier](https://prettier.io), [dprint](https://dprint.dev), or an equivalent instead. + +## Formatters vs. Linters + +**Formatters** are tools that verify and correct whitespace issues in code, such as spacing and newlines. +Formatters typically run very quickly because they are only concerned with changing whitespace, not code logic or naming. + +**Linters** are tools that verify and correct logical and non-whitespace style issues in code, such as naming consistency and bug detection. +Linters often take seconds or more to run because they apply many logical rules to code. + +### Problems with Using Linters as Formatters + +Linters apply much more work than formatters -- often including potentially multiple rounds of rule fixers. +That generally makes them run orders of magnitude slower. + +Additionally, modern formatters such as Prettier are architected in a way that applies formatting to all code regardless of original formatting. +Linters typically run on a rule-by-rule basis, typically resulting in many edge cases and missed coverage in formatting. + +## ESLint Core and Formatting + +Per [ESLint's 2020 Changes to Rule Policies blog post](https://eslint.org/blog/2020/05/changes-to-rules-policies#what-are-the-changes): + +> Stylistic rules are frozen - we won't be adding any more options to stylistic rules. +> We've learned that there's no way to satisfy everyone's personal preferences, and most of the rules already have a lot of difficult-to-understand options. +> Stylistic rules are those related to spacing, conventions, and generally anything that does not highlight an error or a better way to do something. + +We support the ESLint team's decision and backing logic to move away from stylistic rules. +With the exception of bug fixes, no new formatting-related pull requests will be accepted into typescript-eslint. diff --git a/docs/linting/TSLINT.md b/docs/linting/troubleshooting/TSLINT.md similarity index 63% rename from docs/linting/TSLINT.md rename to docs/linting/troubleshooting/TSLINT.md index 0d7954dd3506..a145f9fca61e 100644 --- a/docs/linting/TSLINT.md +++ b/docs/linting/troubleshooting/TSLINT.md @@ -10,9 +10,10 @@ TSLint was a linter equivalent to ESLint that was written specifically to work d ## Migrating from TSLint to ESLint -If you are looking for help in migrating from TSLint to ESLint, see [`tslint-to-eslint-config`](https://github.com/typescript-eslint/tslint-to-eslint-config). +The standard tool to convert a TSLint configuration to the equivalent ESLint configuration is [`tslint-to-eslint-config`](https://github.com/typescript-eslint/tslint-to-eslint-config). +If you are still using TSLint, we strongly recommend you use this tool to switch. -You can look at [`the plugin ROADMAP.md`](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/ROADMAP.md) for an up to date overview of how TSLint rules compare to the ones in this package. +You can look at [the alternatives list](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/TSLINT_RULE_ALTERNATIVES.md) for an up to date overview of how TSLint rules compare to the ones in this package. There is also the ultimate fallback option of using both linters together for a while during your transition if you absolutely have to by using TSLint _within_ ESLint. @@ -27,6 +28,5 @@ TSLint had to reimplement everything from editor extensions to auto-fixing to ru TSLint's backers announced in 2019 that **they would be deprecating TSLint in favor of supporting `typescript-eslint`** in order to benefit the community. You can read more about that here: https://medium.com/palantir/tslint-in-2019-1a144c2317a9. -The TypeScript Team themselves also announced their plans to move the TypeScript codebase from TSLint to `typescript-eslint`, -and they have been big supporters of this project. -More details at https://github.com/microsoft/TypeScript/issues/30553. +The TypeScript team also migrated move the TypeScript codebase from TSLint to `typescript-eslint`, and they have been supporters of this project. +See more details at https://github.com/microsoft/TypeScript/issues/30553. diff --git a/docs/linting/typed-linting/MONOREPOS.md b/docs/linting/typed-linting/MONOREPOS.md new file mode 100644 index 000000000000..a67d05a9c2c0 --- /dev/null +++ b/docs/linting/typed-linting/MONOREPOS.md @@ -0,0 +1,79 @@ +--- +id: monorepos +title: Monorepo Configuration +--- + +If you're using a monorepo, these docs will help you figure out how to setup typed linting. +If you don't want to use typed linting, then you can stop here - you don't need to do anything special. + +Configurations will look different based on which setup you use: + +1. [One root `tsconfig.json`](#one-root-tsconfigjson) +2. [One `tsconfig.json` per package (and an optional one in the root)](#one-tsconfigjson-per-package-and-an-optional-one-in-the-root) + +## One root `tsconfig.json` + +If you only have one `tsconfig.json` file _and_ its `include` paths include all the files you'd like to lint, you can directly use it with typescript-eslint without further configuration. + +If its `include` paths cannot include all files to be linted, we suggest creating a new config called `tsconfig.eslint.json`, that looks something like this: + +```jsonc title="tsconfig.eslint.json" +{ + // extend your base config to share compilerOptions, etc + "extends": "./tsconfig.json", + "compilerOptions": { + // ensure that nobody can accidentally use this config for a build + "noEmit": true + }, + "include": [ + // whatever paths you intend to lint + "src", + "test", + "tools" + ] +} +``` + +Be sure to update your `.eslintrc.js` to point at this new config file. + +## One `tsconfig.json` per package (and an optional one in the root) + +The `parserOptions.project` option introduced in [Linting with Type Information](../TYPED_LINTING.md) accepts an array of relative paths. +Paths may be provided as [Node globs](https://github.com/isaacs/node-glob/blob/f5a57d3d6e19b324522a3fa5bdd5075fd1aa79d1/README.md#glob-primer). + +```js title=".eslintrc.js" +module.exports = { + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:@typescript-eslint/recommended-requiring-type-checking', + ], + parser: '@typescript-eslint/parser', + parserOptions: { + tsconfigRootDir: __dirname, + // Remove this line + project: ['./tsconfig.json'], + // Add this line + project: ['./tsconfig.eslint.json', './packages/*/tsconfig.json'], + }, + plugins: ['@typescript-eslint'], + root: true, +}; +``` + +### Important note regarding large (> 10) multi-package monorepos + +We've had reports that for sufficiently large and/or interdependent projects, you may run into OOMs using this approach. +Our advice is to set it up and test first, as there are very few cases that trigger this OOM. + +See [#1192](https://github.com/typescript-eslint/typescript-eslint/issues/1192) for more information and discussion. + +If you do run into an OOM, please comment on the above issue and let us know about your repo - the more information we have, the better. +As an interim workaround, consider one of the following: + +- Switching to one root `tsconfig.eslint.json` (see below) +- Using a shell script to only lint one package at a time, using your existing config above. + +## Troubleshooting + +If you're having problems getting this working, please have a look at our [Troubleshooting FAQ](../TROUBLESHOOTING.md). diff --git a/lerna.json b/lerna.json index b87f8e43af16..c8dae9f617ce 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "5.30.7", + "version": "5.31.0", "npmClient": "yarn", "useWorkspaces": true, "stream": true diff --git a/packages/ast-spec/CHANGELOG.md b/packages/ast-spec/CHANGELOG.md index ccf543f1660c..35ac41e557f0 100644 --- a/packages/ast-spec/CHANGELOG.md +++ b/packages/ast-spec/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.31.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.30.7...v5.31.0) (2022-07-25) + +**Note:** Version bump only for package @typescript-eslint/ast-spec + + + + + ## [5.30.7](https://github.com/typescript-eslint/typescript-eslint/compare/v5.30.6...v5.30.7) (2022-07-18) **Note:** Version bump only for package @typescript-eslint/ast-spec diff --git a/packages/ast-spec/package.json b/packages/ast-spec/package.json index 4e88e3c53ea5..96ef5ba21eae 100644 --- a/packages/ast-spec/package.json +++ b/packages/ast-spec/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/ast-spec", - "version": "5.30.7", + "version": "5.31.0", "description": "TypeScript-ESTree AST spec", "private": true, "keywords": [ diff --git a/packages/eslint-plugin-internal/CHANGELOG.md b/packages/eslint-plugin-internal/CHANGELOG.md index 51e578a14e1a..c498f667cb8d 100644 --- a/packages/eslint-plugin-internal/CHANGELOG.md +++ b/packages/eslint-plugin-internal/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.31.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.30.7...v5.31.0) (2022-07-25) + +**Note:** Version bump only for package @typescript-eslint/eslint-plugin-internal + + + + + ## [5.30.7](https://github.com/typescript-eslint/typescript-eslint/compare/v5.30.6...v5.30.7) (2022-07-18) **Note:** Version bump only for package @typescript-eslint/eslint-plugin-internal diff --git a/packages/eslint-plugin-internal/package.json b/packages/eslint-plugin-internal/package.json index c6634b6e682f..d86f638ef348 100644 --- a/packages/eslint-plugin-internal/package.json +++ b/packages/eslint-plugin-internal/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/eslint-plugin-internal", - "version": "5.30.7", + "version": "5.31.0", "private": true, "main": "dist/index.js", "scripts": { @@ -14,8 +14,8 @@ }, "dependencies": { "@types/prettier": "*", - "@typescript-eslint/scope-manager": "5.30.7", - "@typescript-eslint/utils": "5.30.7", + "@typescript-eslint/scope-manager": "5.31.0", + "@typescript-eslint/utils": "5.31.0", "prettier": "*" } } diff --git a/packages/eslint-plugin-tslint/CHANGELOG.md b/packages/eslint-plugin-tslint/CHANGELOG.md index 7bc5af01dbba..ad23e4fb63d6 100644 --- a/packages/eslint-plugin-tslint/CHANGELOG.md +++ b/packages/eslint-plugin-tslint/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.31.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.30.7...v5.31.0) (2022-07-25) + +**Note:** Version bump only for package @typescript-eslint/eslint-plugin-tslint + + + + + ## [5.30.7](https://github.com/typescript-eslint/typescript-eslint/compare/v5.30.6...v5.30.7) (2022-07-18) **Note:** Version bump only for package @typescript-eslint/eslint-plugin-tslint diff --git a/packages/eslint-plugin-tslint/package.json b/packages/eslint-plugin-tslint/package.json index d304882a3e5c..8ee49281a2bc 100644 --- a/packages/eslint-plugin-tslint/package.json +++ b/packages/eslint-plugin-tslint/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/eslint-plugin-tslint", - "version": "5.30.7", + "version": "5.31.0", "main": "dist/index.js", "typings": "src/index.ts", "description": "TSLint wrapper plugin for ESLint", @@ -38,7 +38,7 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/utils": "5.30.7", + "@typescript-eslint/utils": "5.31.0", "lodash": "^4.17.21" }, "peerDependencies": { @@ -48,6 +48,6 @@ }, "devDependencies": { "@types/lodash": "*", - "@typescript-eslint/parser": "5.30.7" + "@typescript-eslint/parser": "5.31.0" } } diff --git a/packages/eslint-plugin/CHANGELOG.md b/packages/eslint-plugin/CHANGELOG.md index 21142c15f705..fa2d7bb86beb 100644 --- a/packages/eslint-plugin/CHANGELOG.md +++ b/packages/eslint-plugin/CHANGELOG.md @@ -3,6 +3,24 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.31.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.30.7...v5.31.0) (2022-07-25) + + +### Bug Fixes + +* **eslint-plugin:** [typedef] Support nested array destructuring with type annotation ([#5311](https://github.com/typescript-eslint/typescript-eslint/issues/5311)) ([6d19efe](https://github.com/typescript-eslint/typescript-eslint/commit/6d19efed16d1cf0357ad363b6373d2021c49a8c8)) +* **scope-manager:** handle typeParameters of TSInstantiationExpression ([#5355](https://github.com/typescript-eslint/typescript-eslint/issues/5355)) ([2595ccf](https://github.com/typescript-eslint/typescript-eslint/commit/2595ccf67cd5158edbd6bebd9ac2dbd8bbd8b99c)) + + +### Features + +* **eslint-plugin:** [consistent-generic-ctors] check class field declaration ([#5288](https://github.com/typescript-eslint/typescript-eslint/issues/5288)) ([48f996e](https://github.com/typescript-eslint/typescript-eslint/commit/48f996e8dda79c9c865e8ca6552069902836648b)) +* **eslint-plugin:** [prefer-nullish-coalescing] add ignoreTernaryTests option ([#4965](https://github.com/typescript-eslint/typescript-eslint/issues/4965)) ([f82727f](https://github.com/typescript-eslint/typescript-eslint/commit/f82727ffeb97475c07773ca1d1e5b9609fcc5e68)) + + + + + ## [5.30.7](https://github.com/typescript-eslint/typescript-eslint/compare/v5.30.6...v5.30.7) (2022-07-18) diff --git a/packages/eslint-plugin/README.md b/packages/eslint-plugin/README.md index 5124ce841ae0..f236aeacd811 100644 --- a/packages/eslint-plugin/README.md +++ b/packages/eslint-plugin/README.md @@ -85,7 +85,7 @@ Some highly valuable rules require type-checking in order to be implemented corr Pro Tip: For larger codebases you may want to consider splitting our linting into two separate stages: 1. fast feedback rules which operate purely based on syntax (no type-checking), 2. rules which are based on semantics (type-checking). -**[You can read more about linting with type information here](https://typescript-eslint.io/docs/linting/type-linting)** +**[You can read more about linting with type information here](https://typescript-eslint.io/docs/linting/typed-linting)** ## Supported Rules diff --git a/packages/eslint-plugin/ROADMAP.md b/packages/eslint-plugin/ROADMAP.md index 6ebff3867c65..e108f6140b77 100644 --- a/packages/eslint-plugin/ROADMAP.md +++ b/packages/eslint-plugin/ROADMAP.md @@ -1,726 +1,3 @@ -# TSLint Migration Guide +# This page moved to [TSLINT_RULE_ALTERNATIVES.md](./TSLINT_RULE_ALTERNATIVES.md) -This document serves as a guide to help you migrate from TSLint. -It lists all TSLint rules along side rules from the ESLint ecosystem that are the same or similar. - -## TSLint rules - -βœ… = done
-🌟 = in ESLint core
-πŸ”Œ = in another plugin
-πŸŒ“ = implementations differ or ESLint version is missing functionality
-πŸ›‘ = unimplemented
- -### TypeScript-specific - -| TSLint rule | | ESLint rule | -| --------------------------------- | :-: | ---------------------------------------------------- | -| [`adjacent-overload-signatures`] | βœ… | [`@typescript-eslint/adjacent-overload-signatures`] | -| [`ban-ts-ignore`] | βœ… | [`@typescript-eslint/ban-ts-comment`] | -| [`ban-types`] | πŸŒ“ | [`@typescript-eslint/ban-types`][1] | -| [`invalid-void`] | βœ… | [`@typescript-eslint/no-invalid-void-type`] | -| [`member-access`] | βœ… | [`@typescript-eslint/explicit-member-accessibility`] | -| [`member-ordering`] | βœ… | [`@typescript-eslint/member-ordering`] | -| [`no-any`] | βœ… | [`@typescript-eslint/no-explicit-any`] | -| [`no-empty-interface`] | βœ… | [`@typescript-eslint/no-empty-interface`] | -| [`no-import-side-effect`] | πŸ”Œ | [`import/no-unassigned-import`] | -| [`no-inferrable-types`] | βœ… | [`@typescript-eslint/no-inferrable-types`] | -| [`no-internal-module`] | βœ… | [`@typescript-eslint/prefer-namespace-keyword`] | -| [`no-magic-numbers`] | βœ… | [`@typescript-eslint/no-magic-numbers`] | -| [`no-namespace`] | βœ… | [`@typescript-eslint/no-namespace`] | -| [`no-non-null-assertion`] | βœ… | [`@typescript-eslint/no-non-null-assertion`] | -| [`no-parameter-reassignment`] | βœ… | [`no-param-reassign`][no-param-reassign] | -| [`no-reference`] | βœ… | [`@typescript-eslint/triple-slash-reference`] | -| [`no-unnecessary-type-assertion`] | βœ… | [`@typescript-eslint/no-unnecessary-type-assertion`] | -| [`no-var-requires`] | βœ… | [`@typescript-eslint/no-var-requires`] | -| [`only-arrow-functions`] | πŸ”Œ | [`prefer-arrow/prefer-arrow-functions`] | -| [`prefer-for-of`] | βœ… | [`@typescript-eslint/prefer-for-of`] | -| [`promise-function-async`] | βœ… | [`@typescript-eslint/promise-function-async`] | -| [`typedef-whitespace`] | βœ… | [`@typescript-eslint/type-annotation-spacing`] | -| [`typedef`] | βœ… | [`@typescript-eslint/typedef`] | -| [`unified-signatures`] | βœ… | [`@typescript-eslint/unified-signatures`] | - -[1] The ESLint rule only supports exact string matching, rather than regular expressions
- -### Functionality - -| TSLint rule | | ESLint rule | -| ------------------------------------ | :-: | --------------------------------------------------------------------------------------------------------- | -| [`await-promise`] | βœ… | [`@typescript-eslint/await-thenable`] | -| [`ban-comma-operator`] | 🌟 | [`no-sequences`][no-sequences] | -| [`ban`] | 🌟 | [`no-restricted-globals`][no-restricted-globals] & [`no-restricted-properties`][no-restricted-properties] | -| [`curly`] | 🌟 | [`curly`][curly] | -| [`forin`] | 🌟 | [`guard-for-in`][guard-for-in] | -| [`function-constructor`] | 🌟 | [`no-new-func`][no-new-func] | -| [`import-blacklist`] | 🌟 | [`no-restricted-imports`][no-restricted-imports] | -| [`label-position`] | 🌟 | [`no-unused-labels`][no-unused-labels] (similar) | -| [`no-arg`] | 🌟 | [`no-caller`][no-caller] (also blocks `arguments.caller`) | -| [`no-async-without-await`] | βœ… | [`@typescript-eslint/require-await`] | -| [`no-bitwise`] | 🌟 | [`no-bitwise`][no-bitwise] | -| [`no-conditional-assignment`] | 🌟 | [`no-cond-assign`][no-cond-assign][1] | -| [`no-console`] | 🌟 | [`no-console`][no-console] (configuration works slightly differently) | -| [`no-construct`] | 🌟 | [`no-new-wrappers`][no-new-wrappers] | -| [`no-debugger`] | 🌟 | [`no-debugger`][no-debugger] | -| [`no-duplicate-super`] | 🌟 | [`constructor-super`][constructor-super] | -| [`no-duplicate-switch-case`] | 🌟 | [`no-duplicate-case`][no-duplicate-case] | -| [`no-duplicate-variable`] | 🌟 | [`no-redeclare`][no-redeclare] | -| [`no-dynamic-delete`] | βœ… | [`@typescript-eslint/no-dynamic-delete`] | -| [`no-empty`] | 🌟 | [`no-empty`][no-empty] | -| [`no-eval`] | 🌟 | [`no-eval`][no-eval] | -| [`no-floating-promises`] | βœ… | [`@typescript-eslint/no-floating-promises`] | -| [`no-for-in-array`] | βœ… | [`@typescript-eslint/no-for-in-array`] | -| [`no-implicit-dependencies`] | πŸ”Œ | [`import/no-extraneous-dependencies`] | -| [`no-inferred-empty-object-type`] | πŸ›‘ | N/A | -| [`no-invalid-template-strings`] | 🌟 | [`no-template-curly-in-string`][no-template-curly-in-string] | -| [`no-invalid-this`] | 🌟 | [`no-invalid-this`][no-invalid-this] | -| [`no-misused-new`] | βœ… | [`@typescript-eslint/no-misused-new`] | -| [`no-null-keyword`] | πŸ”Œ | [`no-null/no-null`] (doesn’t handle `null` type) | -| [`no-null-undefined-union`] | πŸ›‘ | N/A | -| [`no-object-literal-type-assertion`] | βœ… | [`@typescript-eslint/consistent-type-assertions`] | -| [`no-promise-as-boolean`] | βœ… | [`@typescript-eslint/no-misused-promises`] | -| [`no-restricted-globals`] | βœ… | [`no-restricted-globals`][no-restricted-globals] | -| [`no-return-await`] | 🌟 | [`no-return-await`][no-return-await] | -| [`no-shadowed-variable`] | 🌟 | [`no-shadow`][no-shadow] | -| [`no-sparse-arrays`] | 🌟 | [`no-sparse-arrays`][no-sparse-arrays] | -| [`no-string-literal`] | 🌟 | [`dot-notation`][dot-notation] | -| [`no-string-throw`] | βœ… | [`@typescript-eslint/no-throw-literal`] | -| [`no-submodule-imports`] | πŸŒ“ | [`import/no-internal-modules`] (slightly different) | -| [`no-switch-case-fall-through`] | 🌟 | [`no-fallthrough`][no-fallthrough] | -| [`no-tautology-expression`] | πŸ›‘ | N/A | -| [`no-this-assignment`] | βœ… | [`@typescript-eslint/no-this-alias`] | -| [`no-unbound-method`] | βœ… | [`@typescript-eslint/unbound-method`] | -| [`no-unnecessary-class`] | βœ… | [`@typescript-eslint/no-extraneous-class`] | -| [`no-unsafe-any`] | πŸŒ“ | [`@typescript-eslint/no-unsafe-member-access`][2] | -| [`no-unsafe-finally`] | 🌟 | [`no-unsafe-finally`][no-unsafe-finally] | -| [`no-unused-expression`] | 🌟 | [`no-unused-expressions`][no-unused-expressions] | -| [`no-unused-variable`] | πŸŒ“ | [`@typescript-eslint/no-unused-vars`] | -| [`no-use-before-declare`] | βœ… | [`@typescript-eslint/no-use-before-define`] | -| [`no-var-keyword`] | 🌟 | [`no-var`][no-var] | -| [`no-void-expression`] | βœ… | [`@typescript-eslint/no-confusing-void-expression`] | -| [`prefer-conditional-expression`] | πŸ›‘ | N/A | -| [`prefer-object-spread`] | 🌟 | [`prefer-object-spread`][prefer-object-spread] | -| [`radix`] | 🌟 | [`radix`][radix] | -| [`restrict-plus-operands`] | βœ… | [`@typescript-eslint/restrict-plus-operands`] | -| [`static-this`] | πŸ›‘ | N/A | -| [`strict-boolean-expressions`] | βœ… | [`@typescript-eslint/strict-boolean-expressions`] | -| [`strict-string-expressions`] | βœ… | [`@typescript-eslint/restrict-plus-operands`] & [`@typescript-eslint/restrict-template-expressions`] | -| [`strict-type-predicates`] | πŸ›‘ | N/A | -| [`switch-default`] | 🌟 | [`default-case`][default-case] | -| [`triple-equals`] | 🌟 | [`eqeqeq`][eqeqeq] | -| [`typeof-compare`] | 🌟 | [`valid-typeof`][valid-typeof] | -| [`unnecessary-constructor`] | 🌟 | [`no-useless-constructor`][no-useless-constructor] | -| [`use-default-type-parameter`] | βœ… | [`@typescript-eslint/no-unnecessary-type-arguments`] | -| [`use-isnan`] | 🌟 | [`use-isnan`][use-isnan] | - -[1] The ESLint rule also supports silencing with an extra set of parentheses (`if ((foo = bar)) {}`)
-[2] Only checks member expressions - -### Maintainability - -| TSLint rule | | ESLint rule | -| ---------------------------- | :-: | -------------------------------------------------- | -| [`cyclomatic-complexity`] | 🌟 | [`complexity`][complexity] | -| [`deprecation`] | πŸ”Œ | [`deprecation/deprecation`] | -| [`eofline`] | 🌟 | [`eol-last`][eol-last] | -| [`indent`] | βœ… | [`@typescript-eslint/indent`] or [Prettier] | -| [`linebreak-style`] | 🌟 | [`linebreak-style`][linebreak-style] or [Prettier] | -| [`max-classes-per-file`] | 🌟 | [`max-classes-per-file`][max-classes-per-file] | -| [`max-file-line-count`] | 🌟 | [`max-lines`][max-lines] | -| [`max-line-length`] | 🌟 | [`max-len`][max-len] or [Prettier] | -| [`no-default-export`] | πŸ”Œ | [`import/no-default-export`] | -| [`no-default-import`] | πŸ›‘ | N/A | -| [`no-duplicate-imports`] | πŸ”Œ | [`import/no-duplicates`] | -| [`no-mergeable-namespace`] | πŸ›‘ | N/A | -| [`no-require-imports`] | βœ… | [`@typescript-eslint/no-require-imports`] | -| [`object-literal-sort-keys`] | πŸŒ“ | [`sort-keys`][sort-keys] [2] | -| [`prefer-const`] | 🌟 | [`prefer-const`][prefer-const] | -| [`prefer-readonly`] | βœ… | [`@typescript-eslint/prefer-readonly`] | -| [`trailing-comma`] | πŸŒ“ | [`comma-dangle`][comma-dangle] or [Prettier] | - -[2] Missing support for blank-line-delimited sections - -### Style - -| TSLint rule | | ESLint rule | -| ----------------------------------- | :-: | ----------------------------------------------------------------------------------- | -| [`align`] | πŸ›‘ | N/A | -| [`array-type`] | βœ… | [`@typescript-eslint/array-type`] | -| [`arrow-parens`] | 🌟 | [`arrow-parens`][arrow-parens] | -| [`arrow-return-shorthand`] | 🌟 | [`arrow-body-style`][arrow-body-style] | -| [`binary-expression-operand-order`] | 🌟 | [`yoda`][yoda] | -| [`callable-types`] | βœ… | [`@typescript-eslint/prefer-function-type`] | -| [`class-name`] | βœ… | [`@typescript-eslint/naming-convention`] | -| [`comment-format`] | 🌟 | [`capitalized-comments`][capitalized-comments] & [`spaced-comment`][spaced-comment] | -| [`comment-type`] | πŸ›‘ | N/A | -| [`completed-docs`] | πŸ”Œ | [`jsdoc/require-jsdoc`] | -| [`encoding`] | πŸ›‘ | N/A | -| [`file-header`] | πŸ”Œ | [`eslint-plugin-header`][plugin:header] or [`-file-header`][plugin:file-header] | -| [`file-name-casing`] | πŸ”Œ | [`unicorn/filename-case`] | -| [`import-spacing`] | πŸ”Œ | Use [Prettier] | -| [`increment-decrement`] | 🌟 | [`no-plusplus`][no-plusplus] | -| [`interface-name`] | βœ… | [`@typescript-eslint/interface-name-prefix`] | -| [`interface-over-type-literal`] | βœ… | [`@typescript-eslint/consistent-type-definitions`] | -| [`jsdoc-format`] | πŸŒ“ | [`valid-jsdoc`][valid-jsdoc] or [`eslint-plugin-jsdoc`][plugin:jsdoc] | -| [`match-default-export-name`] | πŸ›‘ | N/A | -| [`newline-before-return`] | 🌟 | [`padding-line-between-statements`][padding-line-between-statements] [1] | -| [`newline-per-chained-call`] | 🌟 | [`newline-per-chained-call`][newline-per-chained-call] | -| [`new-parens`] | 🌟 | [`new-parens`][new-parens] | -| [`no-angle-bracket-type-assertion`] | βœ… | [`@typescript-eslint/consistent-type-assertions`] | -| [`no-boolean-literal-compare`] | βœ… | [`@typescript-eslint/no-unnecessary-boolean-literal-compare`] | -| [`no-consecutive-blank-lines`] | 🌟 | [`no-multiple-empty-lines`][no-multiple-empty-lines] | -| [`no-irregular-whitespace`] | 🌟 | [`no-irregular-whitespace`][no-irregular-whitespace] with `skipStrings: false` | -| [`no-parameter-properties`] | βœ… | [`@typescript-eslint/parameter-properties`] | -| [`no-redundant-jsdoc`] | πŸ”Œ | [`jsdoc/no-types`] | -| [`no-reference-import`] | βœ… | [`@typescript-eslint/triple-slash-reference`] | -| [`no-trailing-whitespace`] | 🌟 | [`no-trailing-spaces`][no-trailing-spaces] | -| [`no-unnecessary-callback-wrapper`] | πŸ›‘ | N/A and this might be unsafe (i.e. with `forEach`) | -| [`no-unnecessary-else`] | 🌟 | [`no-else-return`][no-else-return] [2] | -| [`no-unnecessary-initializer`] | 🌟 | [`no-undef-init`][no-undef-init] | -| [`no-unnecessary-qualifier`] | βœ… | [`@typescript-eslint/no-unnecessary-qualifier`] | -| [`number-literal-format`] | πŸ›‘ | N/A | -| [`object-literal-key-quotes`] | 🌟 | [`quote-props`][quote-props] | -| [`object-literal-shorthand`] | 🌟 | [`object-shorthand`][object-shorthand] | -| [`one-line`] | 🌟 | [`brace-style`][brace-style] or [Prettier] | -| [`one-variable-per-declaration`] | 🌟 | [`one-var`][one-var] | -| [`ordered-imports`] | πŸŒ“ | [`import/order`] | -| [`prefer-function-over-method`] | 🌟 | [`class-methods-use-this`][class-methods-use-this] | -| [`prefer-method-signature`] | βœ… | [`@typescript-eslint/method-signature-style`] | -| [`prefer-switch`] | πŸ›‘ | N/A | -| [`prefer-template`] | 🌟 | [`prefer-template`][prefer-template] | -| [`prefer-while`] | πŸ›‘ | N/A | -| [`quotemark`] | 🌟 | [`quotes`][quotes] | -| [`return-undefined`] | πŸ›‘ | N/A | -| [`semicolon`] | πŸŒ“ | [`@typescript-eslint/semi`] | -| [`space-before-function-paren`] | 🌟 | [`space-before-function-paren`][space-after-function-paren] | -| [`space-within-parens`] | 🌟 | [`space-in-parens`][space-in-parens] | -| [`switch-final-break`] | πŸ›‘ | N/A | -| [`type-literal-delimiter`] | βœ… | [`@typescript-eslint/member-delimiter-style`] | -| [`unnecessary-bind`] | 🌟 | [`no-extra-bind`][no-extra-bind] | -| [`variable-name`] | βœ… | [`@typescript-eslint/naming-convention`] | -| [`whitespace`] | πŸ”Œ | Use [Prettier] | - -[1] Recommended config: `["error", { blankLine: "always", prev: "*", next: "return" }]`
-[2] Doesn't check other control flow statements, such as `break` or `continue`. - -## `tslint-microsoft-contrib` rules - -Rule listing is [here](https://github.com/Microsoft/tslint-microsoft-contrib#supported-rules). -Deprecated rules are excluded (`missing-jsdoc`, `missing-optional-annotation`, `no-duplicate-case`, `no-duplicate-parameter-names`, `no-function-constructor-with-string-args`, `no-increment-decrement`, `no-empty-interfaces`, `no-missing-visibility-modifiers`, `no-multiple-var-decl`, `no-reserved-keywords`, `no-stateless-class`, `no-var-self`, `no-unnecessary-bind`, and `valid-typeof`). See the docs in the link above to find out what to use instead. - -### Testing - -Relevant plugins: [`chai-expect-keywords`](https://github.com/gavinaiken/eslint-plugin-chai-expect-keywords), [`chai-expect`](https://github.com/Turbo87/eslint-plugin-chai-expect), [`chai-friendly`](https://github.com/ihordiachenko/eslint-plugin-chai-friendly), [`mocha`](https://github.com/lo1tuma/eslint-plugin-mocha), and [`jest`](https://github.com/jest-community/eslint-plugin-jest) - -| `tslint-microsoft-contrib` rule | | ESLint rule | -| ---------------------------------- | :-: | ------------------------- | -| `chai-prefer-contains-to-index-of` | πŸ›‘ | N/A | -| `chai-vague-errors` | πŸ›‘ | N/A | -| `mocha-avoid-only` | πŸ”Œ | [`jest/no-focused-tests`] | -| `mocha-unneeded-done` | πŸ›‘ | N/A | - -### TypeScript - -| `tslint-microsoft-contrib` rule | | ESLint rule | -| ------------------------------- | :-: | ---------------------------------------------------------- | -| `prefer-array-literal` | πŸŒ“ | [`@typescript-eslint/no-array-constructor`] [1] | -| `prefer-type-cast` | πŸ›‘ | N/A | - -[1] ESLint rule is slightly less strict, allowing `new Array()` and `Array(2)`. - -### Miscellaneous - -| `tslint-microsoft-contrib` rule | | ESLint rule | -| ------------------------------------- | :-: | ---------------------------------------------------------------------- | -| `export-name` | πŸ›‘ | N/A ([relevant plugin][plugin:import]) | -| `function-name` | πŸ›‘ | N/A | -| `import-name` | πŸ›‘ | N/A ([relevant plugin][plugin:import]) | -| `informative-docs` | πŸ›‘ | N/A | -| `max-func-body-length` | 🌟 | [`max-statements`][max-statements] | -| `no-banned-terms` | 🌟 | [`no-caller`][no-caller] & [`no-eval`][no-eval] | -| `no-constant-condition` | 🌟 | [`no-constant-condition`][no-constant-condition] | -| `no-control-regex` | 🌟 | [`no-control-regex`][no-control-regex] | -| `no-delete-expression` | βœ… | [`@typescript-eslint/no-dynamic-delete`] | -| `no-empty-line-after-opening-brace` | 🌟 | [`padded-blocks`][padded-blocks] [1] or [Prettier] | -| `no-for-in` | 🌟 | [`no-restricted-syntax`][no-restricted-syntax] [2] | -| `no-function-expression` | 🌟 | [`func-style`][func-style] [3] | -| `no-invalid-regexp` | 🌟 | [`no-invalid-regexp`][no-invalid-regexp] | -| `no-multiline-string` | 🌟 | [`no-multi-str`][no-multi-str] | -| `no-octal-literal` | 🌟 | [`no-octal-escape`][no-octal-escape], see also [`no-octal`][no-octal] | -| `no-regex-spaces` | 🌟 | [`no-regex-spaces`][no-regex-spaces] | -| `no-relative-imports` | πŸ›‘ | N/A, _Not recommended by the maintainers_ | -| `no-single-line-block-comment` | πŸ›‘ | N/A | -| `no-suspicious-comment` | 🌟 | [`no-warning-comments`][no-warning-comments] [4] | -| `no-typeof-undefined` | πŸ›‘ | N/A (this actually has a valid use: checking if a variable is defined) | -| `no-unexternalized-strings` | πŸ›‘ | N/A | -| `no-unnecessary-field-initialization` | πŸŒ“ | [`no-undef-init`][no-undef-init] [5] | -| `no-unnecessary-local-variable` | πŸ›‘ | N/A | -| `no-unnecessary-override` | πŸ›‘ | N/A | -| `no-unnecessary-semicolons` | 🌟 | [`no-extra-semi`][no-extra-semi] or [Prettier] | -| `no-useless-files` | πŸ›‘ | N/A | -| `no-with-statement` | 🌟 | [`no-with`][no-with] | -| `promise-must-complete` | πŸ›‘ | N/A | -| `underscore-consistent-invocation` | πŸ”Œ | [`lodash/chaining`] | -| `use-named-parameter` | πŸ›‘ | N/A | -| `use-simple-attributes` | πŸ›‘ | N/A | - -[1] Enforces blank lines both at the beginning and end of a block
-[2] Recommended config: `["error", "ForInStatement"]`
-[3] Recommended config: `["error", "declaration", { "allowArrowFunctions": true }]`
-[4] Recommended config: `["error", { "terms": ["BUG", "HACK", "FIXME", "LATER", "LATER2", "TODO"], "location": "anywhere" }]`
-[5] Does not check class fields. - -### Security - -| `tslint-microsoft-contrib` rule | | ESLint rule | -| ------------------------------- | :-: | ------------------------------------------------------------------------------------------- | -| `insecure-random` | πŸ”Œ | [`desktop/insecure-random`] or [`@microsoft/sdl/no-insecure-random`] | -| `no-disable-auto-sanitization` | πŸ”Œ | [`@microsoft/sdl/no-msapp-exec-unsafe`] and [`@microsoft/sdl/no-winjs-html-unsafe`] | -| `no-document-domain` | πŸŒ“ | Use [`no-restricted-syntax`][no-restricted-syntax] or [`@microsoft/sdl/no-document-domain`] | -| `no-http-string` | πŸ”Œ | [`@microsoft/sdl/no-insecure-url`] | -| `no-inner-html` | πŸ”Œ | [`@microsoft/sdl/no-inner-html`] and [`@microsoft/sdl/no-html-method`] | -| `no-string-based-set-immediate` | πŸŒ“ | [`@typescript-eslint/no-implied-eval`] | -| `no-string-based-set-interval` | πŸŒ“ | [`@typescript-eslint/no-implied-eval`] | -| `no-string-based-set-timeout` | πŸŒ“ | [`@typescript-eslint/no-implied-eval`] | -| `react-anchor-blank-noopener` | πŸ”Œ | [`react/jsx-no-target-blank`] | -| `react-iframe-missing-sandbox` | πŸ”Œ | [`@microsoft/sdl/react-iframe-missing-sandbox`] | -| `react-no-dangerous-html` | πŸ”Œ | [`react/no-danger`] | -| `non-literal-fs-path` | πŸ”Œ | [`security/detect-non-literal-fs-filename`] | -| `non-literal-require` | πŸ”Œ | [`security/detect-non-literal-require`] | -| `possible-timing-attack` | πŸ”Œ | [`security/detect-possible-timing-attacks`] | - -### Browser - -| `tslint-microsoft-contrib` rule | | ESLint rule | -| ----------------------------------- | :-: | -------------------------------------------------------------------------------------------- | -| `jquery-deferred-must-complete` | πŸ›‘ | N/A | -| `no-backbone-get-set-outside-model` | πŸ›‘ | N/A | -| `no-cookies` | πŸŒ“ | Use [`no-restricted-syntax`][no-restricted-syntax] or [`@microsoft/sdl/no-cookies`] | -| `no-document-write` | πŸŒ“ | Use [`no-restricted-syntax`][no-restricted-syntax] or [`@microsoft/sdl/no-document-write`] | -| `no-exec-script` | πŸŒ“ | Use [`no-restricted-syntax`][no-restricted-syntax] or [`@typescript-eslint/no-implied-eval`] | -| `no-jquery-raw-elements` | πŸ›‘ | N/A | -| `no-unsupported-browser-code` | πŸ›‘ | N/A | -| `react-this-binding-issue` | πŸ›‘ | N/A | -| `react-tsx-curly-spacing` | πŸ”Œ | [`react/jsx-curly-spacing`] | -| `react-unused-props-and-state` | πŸŒ“ | [`react/no-unused-state`] | - -### React A11y - -| `tslint-microsoft-contrib` rule | | ESLint rule | -| ----------------------------------------- | :-: | ---------------------------------------------------------- | -| `react-a11y-accessible-headings` | πŸŒ“ | [`jsx-a11y/heading-has-content`] [1] | -| `react-a11y-anchors` | πŸ”Œ | [`jsx-a11y/anchor-is-valid`] | -| `react-a11y-aria-unsupported-elements` | πŸ”Œ | [`jsx-a11y/aria-unsupported-elements`] | -| `react-a11y-event-has-role` | πŸŒ“ | [`jsx-a11y/no-static-element-interactions`] [2] | -| `react-a11y-image-button-has-alt` | πŸ”Œ | [`jsx-a11y/alt-text`] | -| `react-a11y-img-has-alt` | πŸ”Œ | [`jsx-a11y/alt-text`] | -| `react-a11y-input-elements` | πŸ›‘ | N/A | -| `react-a11y-lang` | πŸ”Œ | [`jsx-a11y/lang`] | -| `react-a11y-meta` | πŸ›‘ | N/A | -| `react-a11y-no-onchange` | πŸ”Œ | [`jsx-a11y/no-onchange`] | -| `react-a11y-props` | πŸ”Œ | [`jsx-a11y/aria-props`] | -| `react-a11y-proptypes` | πŸ”Œ | [`jsx-a11y/aria-proptypes`] | -| `react-a11y-required` | πŸ›‘ | N/A | -| `react-a11y-role-has-required-aria-props` | πŸ”Œ | [`jsx-a11y/role-has-required-aria-props`] | -| `react-a11y-role-supports-aria-props` | πŸ”Œ | [`jsx-a11y/role-supports-aria-props`] | -| `react-a11y-role` | πŸ”Œ | [`jsx-a11y/aria-role`] | -| `react-a11y-tabindex-no-positive` | πŸ”Œ | [`jsx-a11y/tabindex-no-positive`] | -| `react-a11y-titles` | πŸ›‘ | N/A | - -[1] TSLint rule is more strict
-[2] ESLint rule only reports for click handlers - -[prettier]: https://prettier.io - - - -[`adjacent-overload-signatures`]: https://palantir.github.io/tslint/rules/adjacent-overload-signatures -[`ban-ts-ignore`]: https://palantir.github.io/tslint/rules/ban-ts-ignore/ -[`ban-types`]: https://palantir.github.io/tslint/rules/ban-types -[`invalid-void`]: https://palantir.github.io/tslint/rules/invalid-void -[`member-access`]: https://palantir.github.io/tslint/rules/member-access -[`member-ordering`]: https://palantir.github.io/tslint/rules/member-ordering -[`no-any`]: https://palantir.github.io/tslint/rules/no-any -[`no-empty-interface`]: https://palantir.github.io/tslint/rules/no-empty-interface -[`no-import-side-effect`]: https://palantir.github.io/tslint/rules/no-import-side-effect -[`no-inferrable-types`]: https://palantir.github.io/tslint/rules/no-inferrable-types -[`no-internal-module`]: https://palantir.github.io/tslint/rules/no-internal-module -[`no-magic-numbers`]: https://palantir.github.io/tslint/rules/no-magic-numbers -[`no-namespace`]: https://palantir.github.io/tslint/rules/no-namespace -[`no-non-null-assertion`]: https://palantir.github.io/tslint/rules/no-non-null-assertion -[`no-parameter-reassignment`]: https://palantir.github.io/tslint/rules/no-parameter-reassignment -[`no-reference`]: https://palantir.github.io/tslint/rules/no-reference -[`no-unnecessary-type-assertion`]: https://palantir.github.io/tslint/rules/no-unnecessary-type-assertion -[`no-var-requires`]: https://palantir.github.io/tslint/rules/no-var-requires -[`only-arrow-functions`]: https://palantir.github.io/tslint/rules/only-arrow-functions -[`prefer-for-of`]: https://palantir.github.io/tslint/rules/prefer-for-of -[`promise-function-async`]: https://palantir.github.io/tslint/rules/promise-function-async -[`typedef`]: https://palantir.github.io/tslint/rules/typedef -[`typedef-whitespace`]: https://palantir.github.io/tslint/rules/typedef-whitespace -[`unified-signatures`]: https://palantir.github.io/tslint/rules/unified-signatures -[`await-promise`]: https://palantir.github.io/tslint/rules/await-promise -[`ban-comma-operator`]: https://palantir.github.io/tslint/rules/ban-comma-operator -[`ban`]: https://palantir.github.io/tslint/rules/ban -[`curly`]: https://palantir.github.io/tslint/rules/curly -[`forin`]: https://palantir.github.io/tslint/rules/forin -[`function-constructor`]: https://palantir.github.io/tslint/rules/function-constructor -[`import-blacklist`]: https://palantir.github.io/tslint/rules/import-blacklist -[`label-position`]: https://palantir.github.io/tslint/rules/label-position -[`no-arg`]: https://palantir.github.io/tslint/rules/no-arg -[`no-async-without-await`]: https://palantir.github.io/tslint/rules/no-async-without-await -[`no-bitwise`]: https://palantir.github.io/tslint/rules/no-bitwise -[`no-conditional-assignment`]: https://palantir.github.io/tslint/rules/no-conditional-assignment -[`no-console`]: https://palantir.github.io/tslint/rules/no-console -[`no-construct`]: https://palantir.github.io/tslint/rules/no-construct -[`no-debugger`]: https://palantir.github.io/tslint/rules/no-debugger -[`no-duplicate-super`]: https://palantir.github.io/tslint/rules/no-duplicate-super -[`no-duplicate-switch-case`]: https://palantir.github.io/tslint/rules/no-duplicate-switch-case -[`no-duplicate-variable`]: https://palantir.github.io/tslint/rules/no-duplicate-variable -[`no-dynamic-delete`]: https://palantir.github.io/tslint/rules/no-dynamic-delete -[`no-empty`]: https://palantir.github.io/tslint/rules/no-empty -[`no-eval`]: https://palantir.github.io/tslint/rules/no-eval -[`no-floating-promises`]: https://palantir.github.io/tslint/rules/no-floating-promises -[`no-for-in-array`]: https://palantir.github.io/tslint/rules/no-for-in-array -[`no-implicit-dependencies`]: https://palantir.github.io/tslint/rules/no-implicit-dependencies -[`no-inferred-empty-object-type`]: https://palantir.github.io/tslint/rules/no-inferred-empty-object-type -[`no-invalid-template-strings`]: https://palantir.github.io/tslint/rules/no-invalid-template-strings -[`no-invalid-this`]: https://palantir.github.io/tslint/rules/no-invalid-this -[`no-misused-new`]: https://palantir.github.io/tslint/rules/no-misused-new -[`no-null-keyword`]: https://palantir.github.io/tslint/rules/no-null-keyword -[`no-null-undefined-union`]: https://palantir.github.io/tslint/rules/no-null-undefined-union -[`no-object-literal-type-assertion`]: https://palantir.github.io/tslint/rules/no-object-literal-type-assertion -[`no-promise-as-boolean`]: https://palantir.github.io/tslint/rules/no-promise-as-boolean -[`no-restricted-globals`]: https://palantir.github.io/tslint/rules/no-restricted-globals -[`no-return-await`]: https://palantir.github.io/tslint/rules/no-return-await -[`no-shadowed-variable`]: https://palantir.github.io/tslint/rules/no-shadowed-variable -[`no-sparse-arrays`]: https://palantir.github.io/tslint/rules/no-sparse-arrays -[`no-string-literal`]: https://palantir.github.io/tslint/rules/no-string-literal -[`no-string-throw`]: https://palantir.github.io/tslint/rules/no-string-throw -[`no-submodule-imports`]: https://palantir.github.io/tslint/rules/no-submodule-imports -[`no-switch-case-fall-through`]: https://palantir.github.io/tslint/rules/no-switch-case-fall-through -[`no-tautology-expression`]: https://palantir.github.io/tslint/rules/no-tautology-expression -[`no-this-assignment`]: https://palantir.github.io/tslint/rules/no-this-assignment -[`no-unbound-method`]: https://palantir.github.io/tslint/rules/no-unbound-method -[`no-unnecessary-class`]: https://palantir.github.io/tslint/rules/no-unnecessary-class -[`no-unsafe-any`]: https://palantir.github.io/tslint/rules/no-unsafe-any -[`no-unsafe-finally`]: https://palantir.github.io/tslint/rules/no-unsafe-finally -[`no-unused-expression`]: https://palantir.github.io/tslint/rules/no-unused-expression -[`no-unused-variable`]: https://palantir.github.io/tslint/rules/no-unused-variable -[`no-use-before-declare`]: https://palantir.github.io/tslint/rules/no-use-before-declare -[`no-var-keyword`]: https://palantir.github.io/tslint/rules/no-var-keyword -[`no-void-expression`]: https://palantir.github.io/tslint/rules/no-void-expression -[`prefer-conditional-expression`]: https://palantir.github.io/tslint/rules/prefer-conditional-expression -[`prefer-object-spread`]: https://palantir.github.io/tslint/rules/prefer-object-spread -[`radix`]: https://palantir.github.io/tslint/rules/radix -[`restrict-plus-operands`]: https://palantir.github.io/tslint/rules/restrict-plus-operands -[`static-this`]: https://palantir.github.io/tslint/rules/static-this -[`strict-boolean-expressions`]: https://palantir.github.io/tslint/rules/strict-boolean-expressions -[`strict-string-expressions`]: https://palantir.github.io/tslint/rules/strict-string-expressions -[`strict-type-predicates`]: https://palantir.github.io/tslint/rules/strict-type-predicates -[`switch-default`]: https://palantir.github.io/tslint/rules/switch-default -[`triple-equals`]: https://palantir.github.io/tslint/rules/triple-equals -[`typeof-compare`]: https://palantir.github.io/tslint/rules/typeof-compare -[`unnecessary-constructor`]: https://palantir.github.io/tslint/rules/unnecessary-constructor -[`use-default-type-parameter`]: https://palantir.github.io/tslint/rules/use-default-type-parameter -[`use-isnan`]: https://palantir.github.io/tslint/rules/use-isnan -[`cyclomatic-complexity`]: https://palantir.github.io/tslint/rules/cyclomatic-complexity -[`deprecation`]: https://palantir.github.io/tslint/rules/deprecation -[`eofline`]: https://palantir.github.io/tslint/rules/eofline -[`indent`]: https://palantir.github.io/tslint/rules/indent -[`linebreak-style`]: https://palantir.github.io/tslint/rules/linebreak-style -[`max-classes-per-file`]: https://palantir.github.io/tslint/rules/max-classes-per-file -[`max-file-line-count`]: https://palantir.github.io/tslint/rules/max-file-line-count -[`max-line-length`]: https://palantir.github.io/tslint/rules/max-line-length -[`no-default-export`]: https://palantir.github.io/tslint/rules/no-default-export -[`no-default-import`]: https://palantir.github.io/tslint/rules/no-default-import -[`no-duplicate-imports`]: https://palantir.github.io/tslint/rules/no-duplicate-imports -[`no-mergeable-namespace`]: https://palantir.github.io/tslint/rules/no-mergeable-namespace -[`no-require-imports`]: https://palantir.github.io/tslint/rules/no-require-imports -[`object-literal-sort-keys`]: https://palantir.github.io/tslint/rules/object-literal-sort-keys -[`prefer-const`]: https://palantir.github.io/tslint/rules/prefer-const -[`prefer-readonly`]: https://palantir.github.io/tslint/rules/prefer-readonly -[`trailing-comma`]: https://palantir.github.io/tslint/rules/trailing-comma -[`align`]: https://palantir.github.io/tslint/rules/align -[`array-type`]: https://palantir.github.io/tslint/rules/array-type -[`arrow-parens`]: https://palantir.github.io/tslint/rules/arrow-parens -[`arrow-return-shorthand`]: https://palantir.github.io/tslint/rules/arrow-return-shorthand -[`binary-expression-operand-order`]: https://palantir.github.io/tslint/rules/binary-expression-operand-order -[`callable-types`]: https://palantir.github.io/tslint/rules/callable-types -[`class-name`]: https://palantir.github.io/tslint/rules/class-name -[`comment-format`]: https://palantir.github.io/tslint/rules/comment-format -[`comment-type`]: https://palantir.github.io/tslint/rules/comment-type -[`completed-docs`]: https://palantir.github.io/tslint/rules/completed-docs -[`encoding`]: https://palantir.github.io/tslint/rules/encoding -[`file-header`]: https://palantir.github.io/tslint/rules/file-header -[`file-name-casing`]: https://palantir.github.io/tslint/rules/file-name-casing -[`import-spacing`]: https://palantir.github.io/tslint/rules/import-spacing -[`increment-decrement`]: https://palantir.github.io/tslint/rules/increment-decrement -[`interface-name`]: https://palantir.github.io/tslint/rules/interface-name -[`interface-over-type-literal`]: https://palantir.github.io/tslint/rules/interface-over-type-literal -[`jsdoc-format`]: https://palantir.github.io/tslint/rules/jsdoc-format -[`match-default-export-name`]: https://palantir.github.io/tslint/rules/match-default-export-name -[`newline-before-return`]: https://palantir.github.io/tslint/rules/newline-before-return -[`newline-per-chained-call`]: https://palantir.github.io/tslint/rules/newline-per-chained-call -[`new-parens`]: https://palantir.github.io/tslint/rules/new-parens -[`no-angle-bracket-type-assertion`]: https://palantir.github.io/tslint/rules/no-angle-bracket-type-assertion -[`no-boolean-literal-compare`]: https://palantir.github.io/tslint/rules/no-boolean-literal-compare -[`no-consecutive-blank-lines`]: https://palantir.github.io/tslint/rules/no-consecutive-blank-lines -[`no-irregular-whitespace`]: https://palantir.github.io/tslint/rules/no-irregular-whitespace -[`no-parameter-properties`]: https://palantir.github.io/tslint/rules/no-parameter-properties -[`no-redundant-jsdoc`]: https://palantir.github.io/tslint/rules/no-redundant-jsdoc -[`no-reference-import`]: https://palantir.github.io/tslint/rules/no-reference-import -[`no-trailing-whitespace`]: https://palantir.github.io/tslint/rules/no-trailing-whitespace -[`no-unnecessary-callback-wrapper`]: https://palantir.github.io/tslint/rules/no-unnecessary-callback-wrapper -[`no-unnecessary-else`]: https://palantir.github.io/tslint/rules/no-unnecessary-else -[`no-unnecessary-initializer`]: https://palantir.github.io/tslint/rules/no-unnecessary-initializer -[`no-unnecessary-qualifier`]: https://palantir.github.io/tslint/rules/no-unnecessary-qualifier -[`number-literal-format`]: https://palantir.github.io/tslint/rules/number-literal-format -[`object-literal-key-quotes`]: https://palantir.github.io/tslint/rules/object-literal-key-quotes -[`object-literal-shorthand`]: https://palantir.github.io/tslint/rules/object-literal-shorthand -[`one-line`]: https://palantir.github.io/tslint/rules/one-line -[`one-variable-per-declaration`]: https://palantir.github.io/tslint/rules/one-variable-per-declaration -[`ordered-imports`]: https://palantir.github.io/tslint/rules/ordered-imports -[`prefer-function-over-method`]: https://palantir.github.io/tslint/rules/prefer-function-over-method -[`prefer-method-signature`]: https://palantir.github.io/tslint/rules/prefer-method-signature -[`prefer-switch`]: https://palantir.github.io/tslint/rules/prefer-switch -[`prefer-template`]: https://palantir.github.io/tslint/rules/prefer-template -[`prefer-while`]: https://palantir.github.io/tslint/rules/prefer-while -[`quotemark`]: https://palantir.github.io/tslint/rules/quotemark -[`return-undefined`]: https://palantir.github.io/tslint/rules/return-undefined -[`semicolon`]: https://palantir.github.io/tslint/rules/semicolon -[`space-before-function-paren`]: https://palantir.github.io/tslint/rules/space-before-function-paren -[`space-within-parens`]: https://palantir.github.io/tslint/rules/space-within-parens -[`switch-final-break`]: https://palantir.github.io/tslint/rules/switch-final-break -[`type-literal-delimiter`]: https://palantir.github.io/tslint/rules/type-literal-delimiter -[`unnecessary-bind`]: https://palantir.github.io/tslint/rules/unnecessary-bind -[`variable-name`]: https://palantir.github.io/tslint/rules/variable-name -[`whitespace`]: https://palantir.github.io/tslint/rules/whitespace - - - -[no-magic-numbers]: https://eslint.org/docs/rules/no-magic-numbers -[no-param-reassign]: https://eslint.org/docs/rules/no-param-reassign -[no-sequences]: https://eslint.org/docs/rules/no-sequences -[no-restricted-globals]: https://eslint.org/docs/rules/no-restricted-globals -[no-restricted-properties]: https://eslint.org/docs/rules/no-restricted-properties -[no-restricted-syntax]: https://eslint.org/docs/rules/no-restricted-syntax -[curly]: https://eslint.org/docs/rules/curly -[guard-for-in]: https://eslint.org/docs/rules/guard-for-in -[no-new-func]: https://eslint.org/docs/rules/no-new-func -[no-restricted-imports]: https://eslint.org/docs/rules/no-restricted-imports -[no-unused-labels]: https://eslint.org/docs/rules/no-unused-labels -[no-caller]: https://eslint.org/docs/rules/no-caller -[no-bitwise]: https://eslint.org/docs/rules/no-bitwise -[no-cond-assign]: https://eslint.org/docs/rules/no-cond-assign -[no-console]: https://eslint.org/docs/rules/no-console -[no-new-wrappers]: https://eslint.org/docs/rules/no-new-wrappers -[no-debugger]: https://eslint.org/docs/rules/no-debugger -[constructor-super]: https://eslint.org/docs/rules/constructor-super -[no-duplicate-case]: https://eslint.org/docs/rules/no-duplicate-case -[no-redeclare]: https://eslint.org/docs/rules/no-redeclare -[no-empty]: https://eslint.org/docs/rules/no-empty -[no-eval]: https://eslint.org/docs/rules/no-eval -[no-template-curly-in-string]: https://eslint.org/docs/rules/no-template-curly-in-string -[no-invalid-this]: https://eslint.org/docs/rules/no-invalid-this -[no-return-await]: https://eslint.org/docs/rules/no-return-await -[no-shadow]: https://eslint.org/docs/rules/no-shadow -[no-sparse-arrays]: https://eslint.org/docs/rules/no-sparse-arrays -[dot-notation]: https://eslint.org/docs/rules/dot-notation -[no-fallthrough]: https://eslint.org/docs/rules/no-fallthrough -[no-unsafe-finally]: https://eslint.org/docs/rules/no-unsafe-finally -[no-unused-expressions]: https://eslint.org/docs/rules/no-unused-expressions -[no-var]: https://eslint.org/docs/rules/no-var -[prefer-object-spread]: https://eslint.org/docs/rules/prefer-object-spread -[radix]: https://eslint.org/docs/rules/radix -[default-case]: https://eslint.org/docs/rules/default-case -[eqeqeq]: https://eslint.org/docs/rules/eqeqeq -[valid-typeof]: https://eslint.org/docs/rules/valid-typeof -[no-useless-constructor]: https://eslint.org/docs/rules/no-useless-constructor -[use-isnan]: https://eslint.org/docs/rules/use-isnan -[complexity]: https://eslint.org/docs/rules/complexity -[eol-last]: https://eslint.org/docs/rules/eol-last -[linebreak-style]: https://eslint.org/docs/rules/linebreak-style -[max-classes-per-file]: https://eslint.org/docs/rules/max-classes-per-file -[max-lines]: https://eslint.org/docs/rules/max-lines -[max-len]: https://eslint.org/docs/rules/max-len -[sort-keys]: https://eslint.org/docs/rules/sort-keys -[prefer-const]: https://eslint.org/docs/rules/prefer-const -[comma-dangle]: https://eslint.org/docs/rules/comma-dangle -[arrow-parens]: https://eslint.org/docs/rules/arrow-parens -[arrow-body-style]: https://eslint.org/docs/rules/arrow-body-style -[yoda]: https://eslint.org/docs/rules/yoda -[capitalized-comments]: https://eslint.org/docs/rules/capitalized-comments -[spaced-comment]: https://eslint.org/docs/rules/spaced-comment -[no-plusplus]: https://eslint.org/docs/rules/no-plusplus -[valid-jsdoc]: https://eslint.org/docs/rules/valid-jsdoc -[padding-line-between-statements]: https://eslint.org/docs/rules/padding-line-between-statements -[newline-per-chained-call]: https://eslint.org/docs/rules/newline-per-chained-call -[new-parens]: https://eslint.org/docs/rules/new-parens -[no-else-return]: https://eslint.org/docs/rules/no-else-return -[no-multiple-empty-lines]: https://eslint.org/docs/rules/no-multiple-empty-lines -[no-irregular-whitespace]: https://eslint.org/docs/rules/no-irregular-whitespace -[no-trailing-spaces]: https://eslint.org/docs/rules/no-trailing-spaces -[no-undef-init]: https://eslint.org/docs/rules/no-undef-init -[quote-props]: https://eslint.org/docs/rules/quote-props -[object-shorthand]: https://eslint.org/docs/rules/object-shorthand -[brace-style]: https://eslint.org/docs/rules/brace-style -[one-var]: https://eslint.org/docs/rules/one-var -[class-methods-use-this]: https://eslint.org/docs/rules/class-methods-use-this -[prefer-template]: https://eslint.org/docs/rules/prefer-template -[quotes]: https://eslint.org/docs/rules/quotes -[semi]: https://eslint.org/docs/rules/semi -[space-after-function-paren]: https://eslint.org/docs/rules/space-before-function-paren -[space-in-parens]: https://eslint.org/docs/rules/space-in-parens -[no-extra-bind]: https://eslint.org/docs/rules/no-extra-bind -[camelcase]: https://eslint.org/docs/rules/camelcase -[no-underscore-dangle]: https://eslint.org/docs/rules/no-underscore-dangle -[id-blacklist]: https://eslint.org/docs/rules/id-blacklist -[id-match]: https://eslint.org/docs/rules/id-match -[max-statements]: https://eslint.org/docs/rules/max-statements -[no-constant-condition]: https://eslint.org/docs/rules/no-constant-condition -[no-control-regex]: https://eslint.org/docs/rules/no-control-regex -[no-invalid-regexp]: https://eslint.org/docs/rules/no-invalid-regexp -[no-regex-spaces]: https://eslint.org/docs/rules/no-regex-spaces -[no-new-func]: https://eslint.org/docs/rules/no-new-func -[padded-blocks]: https://eslint.org/docs/rules/padded-blocks -[func-style]: https://eslint.org/docs/rules/func-style -[no-multi-str]: https://eslint.org/docs/rules/no-multi-str -[no-octal]: https://eslint.org/docs/rules/no-octal -[no-octal-escape]: https://eslint.org/docs/rules/no-octal-escape -[no-extra-semi]: https://eslint.org/docs/rules/no-extra-semi -[no-with]: https://eslint.org/docs/rules/no-with -[no-warning-comments]: https://eslint.org/docs/rules/no-warning-comments - - - -[`@typescript-eslint/adjacent-overload-signatures`]: https://typescript-eslint.io/rules/adjacent-overload-signatures -[`@typescript-eslint/await-thenable`]: https://typescript-eslint.io/rules/await-thenable -[`@typescript-eslint/ban-types`]: https://typescript-eslint.io/rules/ban-types -[`@typescript-eslint/ban-ts-comment`]: https://typescript-eslint.io/rules/ban-ts-comment -[`@typescript-eslint/consistent-type-assertions`]: https://typescript-eslint.io/rules/consistent-type-assertions -[`@typescript-eslint/consistent-type-definitions`]: https://typescript-eslint.io/rules/consistent-type-definitions -[`@typescript-eslint/explicit-member-accessibility`]: https://typescript-eslint.io/rules/explicit-member-accessibility -[`@typescript-eslint/member-ordering`]: https://typescript-eslint.io/rules/member-ordering -[`@typescript-eslint/method-signature-style`]: https://typescript-eslint.io/rules/method-signature-style -[`@typescript-eslint/no-explicit-any`]: https://typescript-eslint.io/rules/no-explicit-any -[`@typescript-eslint/no-empty-interface`]: https://typescript-eslint.io/rules/no-empty-interface -[`@typescript-eslint/no-implied-eval`]: https://typescript-eslint.io/rules/no-implied-eval -[`@typescript-eslint/no-inferrable-types`]: https://typescript-eslint.io/rules/no-inferrable-types -[`@typescript-eslint/prefer-namespace-keyword`]: https://typescript-eslint.io/rules/prefer-namespace-keyword -[`@typescript-eslint/promise-function-async`]: https://typescript-eslint.io/rules/promise-function-async -[`@typescript-eslint/no-misused-promises`]: https://typescript-eslint.io/rules/no-misused-promises -[`@typescript-eslint/no-namespace`]: https://typescript-eslint.io/rules/no-namespace -[`@typescript-eslint/no-non-null-assertion`]: https://typescript-eslint.io/rules/no-non-null-assertion -[`@typescript-eslint/triple-slash-reference`]: https://typescript-eslint.io/rules/triple-slash-reference -[`@typescript-eslint/unbound-method`]: https://typescript-eslint.io/rules/unbound-method -[`@typescript-eslint/no-unnecessary-type-assertion`]: https://typescript-eslint.io/rules/no-unnecessary-type-assertion -[`@typescript-eslint/no-var-requires`]: https://typescript-eslint.io/rules/no-var-requires -[`@typescript-eslint/type-annotation-spacing`]: https://typescript-eslint.io/rules/type-annotation-spacing -[`@typescript-eslint/typedef`]: https://typescript-eslint.io/rules/typedef -[`@typescript-eslint/unified-signatures`]: https://typescript-eslint.io/rules/unified-signatures -[`@typescript-eslint/no-unnecessary-boolean-literal-compare`]: https://typescript-eslint.io/rules/no-unnecessary-boolean-literal-compare -[`@typescript-eslint/no-misused-new`]: https://typescript-eslint.io/rules/no-misused-new -[`@typescript-eslint/no-this-alias`]: https://typescript-eslint.io/rules/no-this-alias -[`@typescript-eslint/no-throw-literal`]: https://typescript-eslint.io/rules/no-throw-literal -[`@typescript-eslint/no-extraneous-class`]: https://typescript-eslint.io/rules/no-extraneous-class -[`@typescript-eslint/no-unused-vars`]: https://typescript-eslint.io/rules/no-unused-vars -[`@typescript-eslint/no-use-before-define`]: https://typescript-eslint.io/rules/no-use-before-define -[`@typescript-eslint/restrict-plus-operands`]: https://typescript-eslint.io/rules/restrict-plus-operands -[`@typescript-eslint/strict-boolean-expressions`]: https://typescript-eslint.io/rules/strict-boolean-expressions -[`@typescript-eslint/indent`]: https://typescript-eslint.io/rules/indent -[`@typescript-eslint/no-invalid-void-type`]: https://typescript-eslint.io/rules/no-invalid-void-type -[`@typescript-eslint/no-require-imports`]: https://typescript-eslint.io/rules/no-require-imports -[`@typescript-eslint/array-type`]: https://typescript-eslint.io/rules/array-type -[`@typescript-eslint/naming-convention`]: https://typescript-eslint.io/rules/naming-convention -[`@typescript-eslint/interface-name-prefix`]: https://typescript-eslint.io/rules/interface-name-prefix -[`@typescript-eslint/naming-convention`]: https://typescript-eslint.io/rules/naming-convention -[`@typescript-eslint/parameter-properties`]: https://typescript-eslint.io/rules/parameter-properties -[`@typescript-eslint/member-delimiter-style`]: https://typescript-eslint.io/rules/member-delimiter-style -[`@typescript-eslint/prefer-for-of`]: https://typescript-eslint.io/rules/prefer-for-of -[`@typescript-eslint/no-array-constructor`]: https://typescript-eslint.io/rules/no-array-constructor -[`@typescript-eslint/no-dynamic-delete`]: https://typescript-eslint.io/rules/no-dynamic-delete -[`@typescript-eslint/prefer-function-type`]: https://typescript-eslint.io/rules/prefer-function-type -[`@typescript-eslint/prefer-readonly`]: https://typescript-eslint.io/rules/prefer-readonly -[`@typescript-eslint/require-await`]: https://typescript-eslint.io/rules/require-await -[`@typescript-eslint/no-for-in-array`]: https://typescript-eslint.io/rules/no-for-in-array -[`@typescript-eslint/no-unnecessary-qualifier`]: https://typescript-eslint.io/rules/no-unnecessary-qualifier -[`@typescript-eslint/no-unnecessary-type-arguments`]: https://typescript-eslint.io/rules/no-unnecessary-type-arguments -[`@typescript-eslint/semi`]: https://typescript-eslint.io/rules/semi -[`@typescript-eslint/no-floating-promises`]: https://typescript-eslint.io/rules/no-floating-promises -[`@typescript-eslint/no-magic-numbers`]: https://typescript-eslint.io/rules/no-magic-numbers -[`@typescript-eslint/no-unsafe-member-access`]: https://typescript-eslint.io/rules/no-unsafe-member-access -[`@typescript-eslint/restrict-template-expressions`]: https://typescript-eslint.io/rules/restrict-template-expressions -[`@typescript-eslint/no-confusing-void-expression`]: https://typescript-eslint.io/rules/no-confusing-void-expression - - - -[plugin:import]: https://github.com/benmosher/eslint-plugin-import -[`import/no-unassigned-import`]: https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-unassigned-import.md -[`import/no-extraneous-dependencies`]: https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-extraneous-dependencies.md -[`import/no-internal-modules`]: https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-internal-modules.md -[`import/no-deprecated`]: https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-deprecated.md -[`import/no-default-export`]: https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-default-export.md -[`import/no-duplicates`]: https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-duplicates.md -[`import/order`]: https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/order.md - - - -[`react/no-danger`]: https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-danger.md -[`react/jsx-curly-spacing`]: https://github.com/yannickcr/eslint-plugin-react/blob/HEAD/docs/rules/jsx-curly-spacing.md -[`react/jsx-no-target-blank`]: https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-target-blank.md -[`react/no-unused-state`]: https://github.com/yannickcr/eslint-plugin-react/blob/HEAD/docs/rules/no-unused-state.md - - - -[`jsx-a11y/anchor-is-valid`]: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/anchor-is-valid.md -[`jsx-a11y/aria-unsupported-elements`]: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-unsupported-elements.md -[`jsx-a11y/no-static-element-interactions`]: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-static-element-interactions.md -[`jsx-a11y/alt-text`]: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/alt-text.md -[`jsx-a11y/html-has-lang`]: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/html-has-lang.md -[`jsx-a11y/lang`]: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/lang.md -[`jsx-a11y/no-onchange`]: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-onchange.md -[`jsx-a11y/aria-props`]: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-props.md -[`jsx-a11y/aria-proptypes`]: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-proptypes.md -[`jsx-a11y/role-has-required-aria-props`]: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/role-has-required-aria-props.md -[`jsx-a11y/role-supports-aria-props`]: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/role-supports-aria-props.md -[`jsx-a11y/aria-role`]: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-role.md -[`jsx-a11y/tabindex-no-positive`]: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/tabindex-no-positive.md - - - -[`security/detect-non-literal-fs-filename`]: https://github.com/nodesecurity/eslint-plugin-security#detect-non-literal-fs-filename -[`security/detect-non-literal-require`]: https://github.com/nodesecurity/eslint-plugin-security#detect-non-literal-require -[`security/detect-possible-timing-attacks`]: https://github.com/nodesecurity/eslint-plugin-security#detect-possible-timing-attacks - - - -[plugin:jsdoc]: https://github.com/gajus/eslint-plugin-jsdoc -[`jsdoc/require-jsdoc`]: https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-jsdoc -[`jsdoc/no-types`]: https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-no-types - - - -[`@microsoft/sdl/no-cookies`]: https://github.com/microsoft/eslint-plugin-sdl/blob/main/docs/rules/no-cookies.md -[`@microsoft/sdl/no-document-domain`]: https://github.com/microsoft/eslint-plugin-sdl/blob/main/docs/rules/no-document-domain.md -[`@microsoft/sdl/no-document-write`]: https://github.com/microsoft/eslint-plugin-sdl/blob/main/docs/rules/no-document-write.md -[`@microsoft/sdl/no-html-method`]: https://github.com/microsoft/eslint-plugin-sdl/blob/main/docs/rules/no-html-method.md -[`@microsoft/sdl/no-inner-html`]: https://github.com/microsoft/eslint-plugin-sdl/blob/main/docs/rules/no-inner-html.md -[`@microsoft/sdl/no-insecure-random`]: https://github.com/microsoft/eslint-plugin-sdl/blob/main/docs/rules/no-insecure-random.md -[`@microsoft/sdl/no-insecure-url`]: https://github.com/microsoft/eslint-plugin-sdl/blob/main/docs/rules/no-insecure-url.md -[`@microsoft/sdl/no-msapp-exec-unsafe`]: https://github.com/microsoft/eslint-plugin-sdl/blob/main/docs/rules/no-msapp-exec-unsafe.md -[`@microsoft/sdl/no-winjs-html-unsafe`]: https://github.com/microsoft/eslint-plugin-sdl/blob/main/docs/rules/no-winjs-html-unsafe.md -[`@microsoft/sdl/react-iframe-missing-sandbox`]: https://github.com/microsoft/eslint-plugin-sdl/blob/main/docs/rules/react-iframe-missing-sandbox.md - - - -[`prefer-arrow/prefer-arrow-functions`]: https://github.com/TristonJ/eslint-plugin-prefer-arrow -[plugin:promise]: https://github.com/xjamundx/eslint-plugin-promise -[plugin:header]: https://github.com/Stuk/eslint-plugin-header -[plugin:file-header]: https://github.com/Sekhmet/eslint-plugin-file-header -[plugin:compat]: https://github.com/amilajack/eslint-plugin-compat -[`no-null/no-null`]: https://github.com/nene/eslint-plugin-no-null -[`unicorn/filename-case`]: https://github.com/sindresorhus/eslint-plugin-unicorn/blob/master/docs/rules/filename-case.md -[`jest/no-focused-tests`]: https://github.com/jest-community/eslint-plugin-jest/blob/main/docs/rules/no-focused-tests.md -[`jsx-a11y/heading-has-content`]: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/heading-has-content.md -[`lodash/chaining`]: https://github.com/wix/eslint-plugin-lodash/blob/master/docs/rules/chaining.md -[`deprecation/deprecation`]: https://github.com/gund/eslint-plugin-deprecation -[`desktop/insecure-random`]: https://github.com/desktop/desktop/blob/development/eslint-rules/insecure-random.js +πŸ‘‹ diff --git a/packages/eslint-plugin/TSLINT_RULE_ALTERNATIVES.md b/packages/eslint-plugin/TSLINT_RULE_ALTERNATIVES.md new file mode 100644 index 000000000000..097de8938048 --- /dev/null +++ b/packages/eslint-plugin/TSLINT_RULE_ALTERNATIVES.md @@ -0,0 +1,728 @@ +# TSLint Rule Alternatives + +This document serves as a guide to help you migrate from TSLint. +It lists all TSLint rules along side rules from the ESLint ecosystem that are the same or similar. + +> For a tool that migrates a TSLint config to the closest possible ESLint config, see [`tslint-to-eslint-config`](https://github.com/typescript-eslint/tslint-to-eslint-config). + +## TSLint rules + +βœ… = done
+🌟 = in ESLint core
+πŸ”Œ = in another plugin
+πŸŒ“ = implementations differ or ESLint version is missing functionality
+πŸ›‘ = unimplemented
+ +### TypeScript-specific + +| TSLint rule | | ESLint rule | +| --------------------------------- | :-: | ---------------------------------------------------- | +| [`adjacent-overload-signatures`] | βœ… | [`@typescript-eslint/adjacent-overload-signatures`] | +| [`ban-ts-ignore`] | βœ… | [`@typescript-eslint/ban-ts-comment`] | +| [`ban-types`] | πŸŒ“ | [`@typescript-eslint/ban-types`][1] | +| [`invalid-void`] | βœ… | [`@typescript-eslint/no-invalid-void-type`] | +| [`member-access`] | βœ… | [`@typescript-eslint/explicit-member-accessibility`] | +| [`member-ordering`] | βœ… | [`@typescript-eslint/member-ordering`] | +| [`no-any`] | βœ… | [`@typescript-eslint/no-explicit-any`] | +| [`no-empty-interface`] | βœ… | [`@typescript-eslint/no-empty-interface`] | +| [`no-import-side-effect`] | πŸ”Œ | [`import/no-unassigned-import`] | +| [`no-inferrable-types`] | βœ… | [`@typescript-eslint/no-inferrable-types`] | +| [`no-internal-module`] | βœ… | [`@typescript-eslint/prefer-namespace-keyword`] | +| [`no-magic-numbers`] | βœ… | [`@typescript-eslint/no-magic-numbers`] | +| [`no-namespace`] | βœ… | [`@typescript-eslint/no-namespace`] | +| [`no-non-null-assertion`] | βœ… | [`@typescript-eslint/no-non-null-assertion`] | +| [`no-parameter-reassignment`] | βœ… | [`no-param-reassign`][no-param-reassign] | +| [`no-reference`] | βœ… | [`@typescript-eslint/triple-slash-reference`] | +| [`no-unnecessary-type-assertion`] | βœ… | [`@typescript-eslint/no-unnecessary-type-assertion`] | +| [`no-var-requires`] | βœ… | [`@typescript-eslint/no-var-requires`] | +| [`only-arrow-functions`] | πŸ”Œ | [`prefer-arrow/prefer-arrow-functions`] | +| [`prefer-for-of`] | βœ… | [`@typescript-eslint/prefer-for-of`] | +| [`promise-function-async`] | βœ… | [`@typescript-eslint/promise-function-async`] | +| [`typedef-whitespace`] | βœ… | [`@typescript-eslint/type-annotation-spacing`] | +| [`typedef`] | βœ… | [`@typescript-eslint/typedef`] | +| [`unified-signatures`] | βœ… | [`@typescript-eslint/unified-signatures`] | + +[1] The ESLint rule only supports exact string matching, rather than regular expressions
+ +### Functionality + +| TSLint rule | | ESLint rule | +| ------------------------------------ | :-: | --------------------------------------------------------------------------------------------------------- | +| [`await-promise`] | βœ… | [`@typescript-eslint/await-thenable`] | +| [`ban-comma-operator`] | 🌟 | [`no-sequences`][no-sequences] | +| [`ban`] | 🌟 | [`no-restricted-globals`][no-restricted-globals] & [`no-restricted-properties`][no-restricted-properties] | +| [`curly`] | 🌟 | [`curly`][curly] | +| [`forin`] | 🌟 | [`guard-for-in`][guard-for-in] | +| [`function-constructor`] | 🌟 | [`no-new-func`][no-new-func] | +| [`import-blacklist`] | 🌟 | [`no-restricted-imports`][no-restricted-imports] | +| [`label-position`] | 🌟 | [`no-unused-labels`][no-unused-labels] (similar) | +| [`no-arg`] | 🌟 | [`no-caller`][no-caller] (also blocks `arguments.caller`) | +| [`no-async-without-await`] | βœ… | [`@typescript-eslint/require-await`] | +| [`no-bitwise`] | 🌟 | [`no-bitwise`][no-bitwise] | +| [`no-conditional-assignment`] | 🌟 | [`no-cond-assign`][no-cond-assign][1] | +| [`no-console`] | 🌟 | [`no-console`][no-console] (configuration works slightly differently) | +| [`no-construct`] | 🌟 | [`no-new-wrappers`][no-new-wrappers] | +| [`no-debugger`] | 🌟 | [`no-debugger`][no-debugger] | +| [`no-duplicate-super`] | 🌟 | [`constructor-super`][constructor-super] | +| [`no-duplicate-switch-case`] | 🌟 | [`no-duplicate-case`][no-duplicate-case] | +| [`no-duplicate-variable`] | 🌟 | [`no-redeclare`][no-redeclare] | +| [`no-dynamic-delete`] | βœ… | [`@typescript-eslint/no-dynamic-delete`] | +| [`no-empty`] | 🌟 | [`no-empty`][no-empty] | +| [`no-eval`] | 🌟 | [`no-eval`][no-eval] | +| [`no-floating-promises`] | βœ… | [`@typescript-eslint/no-floating-promises`] | +| [`no-for-in-array`] | βœ… | [`@typescript-eslint/no-for-in-array`] | +| [`no-implicit-dependencies`] | πŸ”Œ | [`import/no-extraneous-dependencies`] | +| [`no-inferred-empty-object-type`] | πŸ›‘ | N/A | +| [`no-invalid-template-strings`] | 🌟 | [`no-template-curly-in-string`][no-template-curly-in-string] | +| [`no-invalid-this`] | 🌟 | [`no-invalid-this`][no-invalid-this] | +| [`no-misused-new`] | βœ… | [`@typescript-eslint/no-misused-new`] | +| [`no-null-keyword`] | πŸ”Œ | [`no-null/no-null`] (doesn’t handle `null` type) | +| [`no-null-undefined-union`] | πŸ›‘ | N/A | +| [`no-object-literal-type-assertion`] | βœ… | [`@typescript-eslint/consistent-type-assertions`] | +| [`no-promise-as-boolean`] | βœ… | [`@typescript-eslint/no-misused-promises`] | +| [`no-restricted-globals`] | βœ… | [`no-restricted-globals`][no-restricted-globals] | +| [`no-return-await`] | 🌟 | [`no-return-await`][no-return-await] | +| [`no-shadowed-variable`] | 🌟 | [`no-shadow`][no-shadow] | +| [`no-sparse-arrays`] | 🌟 | [`no-sparse-arrays`][no-sparse-arrays] | +| [`no-string-literal`] | 🌟 | [`dot-notation`][dot-notation] | +| [`no-string-throw`] | βœ… | [`@typescript-eslint/no-throw-literal`] | +| [`no-submodule-imports`] | πŸŒ“ | [`import/no-internal-modules`] (slightly different) | +| [`no-switch-case-fall-through`] | 🌟 | [`no-fallthrough`][no-fallthrough] | +| [`no-tautology-expression`] | πŸ›‘ | N/A | +| [`no-this-assignment`] | βœ… | [`@typescript-eslint/no-this-alias`] | +| [`no-unbound-method`] | βœ… | [`@typescript-eslint/unbound-method`] | +| [`no-unnecessary-class`] | βœ… | [`@typescript-eslint/no-extraneous-class`] | +| [`no-unsafe-any`] | πŸŒ“ | [`@typescript-eslint/no-unsafe-member-access`][2] | +| [`no-unsafe-finally`] | 🌟 | [`no-unsafe-finally`][no-unsafe-finally] | +| [`no-unused-expression`] | 🌟 | [`no-unused-expressions`][no-unused-expressions] | +| [`no-unused-variable`] | πŸŒ“ | [`@typescript-eslint/no-unused-vars`] | +| [`no-use-before-declare`] | βœ… | [`@typescript-eslint/no-use-before-define`] | +| [`no-var-keyword`] | 🌟 | [`no-var`][no-var] | +| [`no-void-expression`] | βœ… | [`@typescript-eslint/no-confusing-void-expression`] | +| [`prefer-conditional-expression`] | πŸ›‘ | N/A | +| [`prefer-object-spread`] | 🌟 | [`prefer-object-spread`][prefer-object-spread] | +| [`radix`] | 🌟 | [`radix`][radix] | +| [`restrict-plus-operands`] | βœ… | [`@typescript-eslint/restrict-plus-operands`] | +| [`static-this`] | πŸ›‘ | N/A | +| [`strict-boolean-expressions`] | βœ… | [`@typescript-eslint/strict-boolean-expressions`] | +| [`strict-string-expressions`] | βœ… | [`@typescript-eslint/restrict-plus-operands`] & [`@typescript-eslint/restrict-template-expressions`] | +| [`strict-type-predicates`] | πŸ›‘ | N/A | +| [`switch-default`] | 🌟 | [`default-case`][default-case] | +| [`triple-equals`] | 🌟 | [`eqeqeq`][eqeqeq] | +| [`typeof-compare`] | 🌟 | [`valid-typeof`][valid-typeof] | +| [`unnecessary-constructor`] | 🌟 | [`no-useless-constructor`][no-useless-constructor] | +| [`use-default-type-parameter`] | βœ… | [`@typescript-eslint/no-unnecessary-type-arguments`] | +| [`use-isnan`] | 🌟 | [`use-isnan`][use-isnan] | + +[1] The ESLint rule also supports silencing with an extra set of parentheses (`if ((foo = bar)) {}`)
+[2] Only checks member expressions + +### Maintainability + +| TSLint rule | | ESLint rule | +| ---------------------------- | :-: | -------------------------------------------------- | +| [`cyclomatic-complexity`] | 🌟 | [`complexity`][complexity] | +| [`deprecation`] | πŸ”Œ | [`deprecation/deprecation`] | +| [`eofline`] | 🌟 | [`eol-last`][eol-last] | +| [`indent`] | βœ… | [`@typescript-eslint/indent`] or [Prettier] | +| [`linebreak-style`] | 🌟 | [`linebreak-style`][linebreak-style] or [Prettier] | +| [`max-classes-per-file`] | 🌟 | [`max-classes-per-file`][max-classes-per-file] | +| [`max-file-line-count`] | 🌟 | [`max-lines`][max-lines] | +| [`max-line-length`] | 🌟 | [`max-len`][max-len] or [Prettier] | +| [`no-default-export`] | πŸ”Œ | [`import/no-default-export`] | +| [`no-default-import`] | πŸ›‘ | N/A | +| [`no-duplicate-imports`] | πŸ”Œ | [`import/no-duplicates`] | +| [`no-mergeable-namespace`] | πŸ›‘ | N/A | +| [`no-require-imports`] | βœ… | [`@typescript-eslint/no-require-imports`] | +| [`object-literal-sort-keys`] | πŸŒ“ | [`sort-keys`][sort-keys] [2] | +| [`prefer-const`] | 🌟 | [`prefer-const`][prefer-const] | +| [`prefer-readonly`] | βœ… | [`@typescript-eslint/prefer-readonly`] | +| [`trailing-comma`] | πŸŒ“ | [`comma-dangle`][comma-dangle] or [Prettier] | + +[2] Missing support for blank-line-delimited sections + +### Style + +| TSLint rule | | ESLint rule | +| ----------------------------------- | :-: | ----------------------------------------------------------------------------------- | +| [`align`] | πŸ›‘ | N/A | +| [`array-type`] | βœ… | [`@typescript-eslint/array-type`] | +| [`arrow-parens`] | 🌟 | [`arrow-parens`][arrow-parens] | +| [`arrow-return-shorthand`] | 🌟 | [`arrow-body-style`][arrow-body-style] | +| [`binary-expression-operand-order`] | 🌟 | [`yoda`][yoda] | +| [`callable-types`] | βœ… | [`@typescript-eslint/prefer-function-type`] | +| [`class-name`] | βœ… | [`@typescript-eslint/naming-convention`] | +| [`comment-format`] | 🌟 | [`capitalized-comments`][capitalized-comments] & [`spaced-comment`][spaced-comment] | +| [`comment-type`] | πŸ›‘ | N/A | +| [`completed-docs`] | πŸ”Œ | [`jsdoc/require-jsdoc`] | +| [`encoding`] | πŸ›‘ | N/A | +| [`file-header`] | πŸ”Œ | [`eslint-plugin-header`][plugin:header] or [`-file-header`][plugin:file-header] | +| [`file-name-casing`] | πŸ”Œ | [`unicorn/filename-case`] | +| [`import-spacing`] | πŸ”Œ | Use [Prettier] | +| [`increment-decrement`] | 🌟 | [`no-plusplus`][no-plusplus] | +| [`interface-name`] | βœ… | [`@typescript-eslint/interface-name-prefix`] | +| [`interface-over-type-literal`] | βœ… | [`@typescript-eslint/consistent-type-definitions`] | +| [`jsdoc-format`] | πŸŒ“ | [`valid-jsdoc`][valid-jsdoc] or [`eslint-plugin-jsdoc`][plugin:jsdoc] | +| [`match-default-export-name`] | πŸ›‘ | N/A | +| [`newline-before-return`] | 🌟 | [`padding-line-between-statements`][padding-line-between-statements] [1] | +| [`newline-per-chained-call`] | 🌟 | [`newline-per-chained-call`][newline-per-chained-call] | +| [`new-parens`] | 🌟 | [`new-parens`][new-parens] | +| [`no-angle-bracket-type-assertion`] | βœ… | [`@typescript-eslint/consistent-type-assertions`] | +| [`no-boolean-literal-compare`] | βœ… | [`@typescript-eslint/no-unnecessary-boolean-literal-compare`] | +| [`no-consecutive-blank-lines`] | 🌟 | [`no-multiple-empty-lines`][no-multiple-empty-lines] | +| [`no-irregular-whitespace`] | 🌟 | [`no-irregular-whitespace`][no-irregular-whitespace] with `skipStrings: false` | +| [`no-parameter-properties`] | βœ… | [`@typescript-eslint/parameter-properties`] | +| [`no-redundant-jsdoc`] | πŸ”Œ | [`jsdoc/no-types`] | +| [`no-reference-import`] | βœ… | [`@typescript-eslint/triple-slash-reference`] | +| [`no-trailing-whitespace`] | 🌟 | [`no-trailing-spaces`][no-trailing-spaces] | +| [`no-unnecessary-callback-wrapper`] | πŸ›‘ | N/A and this might be unsafe (i.e. with `forEach`) | +| [`no-unnecessary-else`] | 🌟 | [`no-else-return`][no-else-return] [2] | +| [`no-unnecessary-initializer`] | 🌟 | [`no-undef-init`][no-undef-init] | +| [`no-unnecessary-qualifier`] | βœ… | [`@typescript-eslint/no-unnecessary-qualifier`] | +| [`number-literal-format`] | πŸ›‘ | N/A | +| [`object-literal-key-quotes`] | 🌟 | [`quote-props`][quote-props] | +| [`object-literal-shorthand`] | 🌟 | [`object-shorthand`][object-shorthand] | +| [`one-line`] | 🌟 | [`brace-style`][brace-style] or [Prettier] | +| [`one-variable-per-declaration`] | 🌟 | [`one-var`][one-var] | +| [`ordered-imports`] | πŸŒ“ | [`import/order`] | +| [`prefer-function-over-method`] | 🌟 | [`class-methods-use-this`][class-methods-use-this] | +| [`prefer-method-signature`] | βœ… | [`@typescript-eslint/method-signature-style`] | +| [`prefer-switch`] | πŸ›‘ | N/A | +| [`prefer-template`] | 🌟 | [`prefer-template`][prefer-template] | +| [`prefer-while`] | πŸ›‘ | N/A | +| [`quotemark`] | 🌟 | [`quotes`][quotes] | +| [`return-undefined`] | πŸ›‘ | N/A | +| [`semicolon`] | πŸŒ“ | [`@typescript-eslint/semi`] | +| [`space-before-function-paren`] | 🌟 | [`space-before-function-paren`][space-after-function-paren] | +| [`space-within-parens`] | 🌟 | [`space-in-parens`][space-in-parens] | +| [`switch-final-break`] | πŸ›‘ | N/A | +| [`type-literal-delimiter`] | βœ… | [`@typescript-eslint/member-delimiter-style`] | +| [`unnecessary-bind`] | 🌟 | [`no-extra-bind`][no-extra-bind] | +| [`variable-name`] | βœ… | [`@typescript-eslint/naming-convention`] | +| [`whitespace`] | πŸ”Œ | Use [Prettier] | + +[1] Recommended config: `["error", { blankLine: "always", prev: "*", next: "return" }]`
+[2] Doesn't check other control flow statements, such as `break` or `continue`. + +## `tslint-microsoft-contrib` rules + +Rule listing is [here](https://github.com/Microsoft/tslint-microsoft-contrib#supported-rules). +Deprecated rules are excluded (`missing-jsdoc`, `missing-optional-annotation`, `no-duplicate-case`, `no-duplicate-parameter-names`, `no-function-constructor-with-string-args`, `no-increment-decrement`, `no-empty-interfaces`, `no-missing-visibility-modifiers`, `no-multiple-var-decl`, `no-reserved-keywords`, `no-stateless-class`, `no-var-self`, `no-unnecessary-bind`, and `valid-typeof`). See the docs in the link above to find out what to use instead. + +### Testing + +Relevant plugins: [`chai-expect-keywords`](https://github.com/gavinaiken/eslint-plugin-chai-expect-keywords), [`chai-expect`](https://github.com/Turbo87/eslint-plugin-chai-expect), [`chai-friendly`](https://github.com/ihordiachenko/eslint-plugin-chai-friendly), [`mocha`](https://github.com/lo1tuma/eslint-plugin-mocha), and [`jest`](https://github.com/jest-community/eslint-plugin-jest) + +| `tslint-microsoft-contrib` rule | | ESLint rule | +| ---------------------------------- | :-: | ------------------------- | +| `chai-prefer-contains-to-index-of` | πŸ›‘ | N/A | +| `chai-vague-errors` | πŸ›‘ | N/A | +| `mocha-avoid-only` | πŸ”Œ | [`jest/no-focused-tests`] | +| `mocha-unneeded-done` | πŸ›‘ | N/A | + +### TypeScript + +| `tslint-microsoft-contrib` rule | | ESLint rule | +| ------------------------------- | :-: | ---------------------------------------------------------- | +| `prefer-array-literal` | πŸŒ“ | [`@typescript-eslint/no-array-constructor`] [1] | +| `prefer-type-cast` | πŸ›‘ | N/A | + +[1] ESLint rule is slightly less strict, allowing `new Array()` and `Array(2)`. + +### Miscellaneous + +| `tslint-microsoft-contrib` rule | | ESLint rule | +| ------------------------------------- | :-: | ---------------------------------------------------------------------- | +| `export-name` | πŸ›‘ | N/A ([relevant plugin][plugin:import]) | +| `function-name` | πŸ›‘ | N/A | +| `import-name` | πŸ›‘ | N/A ([relevant plugin][plugin:import]) | +| `informative-docs` | πŸ›‘ | N/A | +| `max-func-body-length` | 🌟 | [`max-statements`][max-statements] | +| `no-banned-terms` | 🌟 | [`no-caller`][no-caller] & [`no-eval`][no-eval] | +| `no-constant-condition` | 🌟 | [`no-constant-condition`][no-constant-condition] | +| `no-control-regex` | 🌟 | [`no-control-regex`][no-control-regex] | +| `no-delete-expression` | βœ… | [`@typescript-eslint/no-dynamic-delete`] | +| `no-empty-line-after-opening-brace` | 🌟 | [`padded-blocks`][padded-blocks] [1] or [Prettier] | +| `no-for-in` | 🌟 | [`no-restricted-syntax`][no-restricted-syntax] [2] | +| `no-function-expression` | 🌟 | [`func-style`][func-style] [3] | +| `no-invalid-regexp` | 🌟 | [`no-invalid-regexp`][no-invalid-regexp] | +| `no-multiline-string` | 🌟 | [`no-multi-str`][no-multi-str] | +| `no-octal-literal` | 🌟 | [`no-octal-escape`][no-octal-escape], see also [`no-octal`][no-octal] | +| `no-regex-spaces` | 🌟 | [`no-regex-spaces`][no-regex-spaces] | +| `no-relative-imports` | πŸ›‘ | N/A, _Not recommended by the maintainers_ | +| `no-single-line-block-comment` | πŸ›‘ | N/A | +| `no-suspicious-comment` | 🌟 | [`no-warning-comments`][no-warning-comments] [4] | +| `no-typeof-undefined` | πŸ›‘ | N/A (this actually has a valid use: checking if a variable is defined) | +| `no-unexternalized-strings` | πŸ›‘ | N/A | +| `no-unnecessary-field-initialization` | πŸŒ“ | [`no-undef-init`][no-undef-init] [5] | +| `no-unnecessary-local-variable` | πŸ›‘ | N/A | +| `no-unnecessary-override` | πŸ›‘ | N/A | +| `no-unnecessary-semicolons` | 🌟 | [`no-extra-semi`][no-extra-semi] or [Prettier] | +| `no-useless-files` | πŸ›‘ | N/A | +| `no-with-statement` | 🌟 | [`no-with`][no-with] | +| `promise-must-complete` | πŸ›‘ | N/A | +| `underscore-consistent-invocation` | πŸ”Œ | [`lodash/chaining`] | +| `use-named-parameter` | πŸ›‘ | N/A | +| `use-simple-attributes` | πŸ›‘ | N/A | + +[1] Enforces blank lines both at the beginning and end of a block
+[2] Recommended config: `["error", "ForInStatement"]`
+[3] Recommended config: `["error", "declaration", { "allowArrowFunctions": true }]`
+[4] Recommended config: `["error", { "terms": ["BUG", "HACK", "FIXME", "LATER", "LATER2", "TODO"], "location": "anywhere" }]`
+[5] Does not check class fields. + +### Security + +| `tslint-microsoft-contrib` rule | | ESLint rule | +| ------------------------------- | :-: | ------------------------------------------------------------------------------------------- | +| `insecure-random` | πŸ”Œ | [`desktop/insecure-random`] or [`@microsoft/sdl/no-insecure-random`] | +| `no-disable-auto-sanitization` | πŸ”Œ | [`@microsoft/sdl/no-msapp-exec-unsafe`] and [`@microsoft/sdl/no-winjs-html-unsafe`] | +| `no-document-domain` | πŸŒ“ | Use [`no-restricted-syntax`][no-restricted-syntax] or [`@microsoft/sdl/no-document-domain`] | +| `no-http-string` | πŸ”Œ | [`@microsoft/sdl/no-insecure-url`] | +| `no-inner-html` | πŸ”Œ | [`@microsoft/sdl/no-inner-html`] and [`@microsoft/sdl/no-html-method`] | +| `no-string-based-set-immediate` | πŸŒ“ | [`@typescript-eslint/no-implied-eval`] | +| `no-string-based-set-interval` | πŸŒ“ | [`@typescript-eslint/no-implied-eval`] | +| `no-string-based-set-timeout` | πŸŒ“ | [`@typescript-eslint/no-implied-eval`] | +| `react-anchor-blank-noopener` | πŸ”Œ | [`react/jsx-no-target-blank`] | +| `react-iframe-missing-sandbox` | πŸ”Œ | [`@microsoft/sdl/react-iframe-missing-sandbox`] | +| `react-no-dangerous-html` | πŸ”Œ | [`react/no-danger`] | +| `non-literal-fs-path` | πŸ”Œ | [`security/detect-non-literal-fs-filename`] | +| `non-literal-require` | πŸ”Œ | [`security/detect-non-literal-require`] | +| `possible-timing-attack` | πŸ”Œ | [`security/detect-possible-timing-attacks`] | + +### Browser + +| `tslint-microsoft-contrib` rule | | ESLint rule | +| ----------------------------------- | :-: | -------------------------------------------------------------------------------------------- | +| `jquery-deferred-must-complete` | πŸ›‘ | N/A | +| `no-backbone-get-set-outside-model` | πŸ›‘ | N/A | +| `no-cookies` | πŸŒ“ | Use [`no-restricted-syntax`][no-restricted-syntax] or [`@microsoft/sdl/no-cookies`] | +| `no-document-write` | πŸŒ“ | Use [`no-restricted-syntax`][no-restricted-syntax] or [`@microsoft/sdl/no-document-write`] | +| `no-exec-script` | πŸŒ“ | Use [`no-restricted-syntax`][no-restricted-syntax] or [`@typescript-eslint/no-implied-eval`] | +| `no-jquery-raw-elements` | πŸ›‘ | N/A | +| `no-unsupported-browser-code` | πŸ›‘ | N/A | +| `react-this-binding-issue` | πŸ›‘ | N/A | +| `react-tsx-curly-spacing` | πŸ”Œ | [`react/jsx-curly-spacing`] | +| `react-unused-props-and-state` | πŸŒ“ | [`react/no-unused-state`] | + +### React A11y + +| `tslint-microsoft-contrib` rule | | ESLint rule | +| ----------------------------------------- | :-: | ---------------------------------------------------------- | +| `react-a11y-accessible-headings` | πŸŒ“ | [`jsx-a11y/heading-has-content`] [1] | +| `react-a11y-anchors` | πŸ”Œ | [`jsx-a11y/anchor-is-valid`] | +| `react-a11y-aria-unsupported-elements` | πŸ”Œ | [`jsx-a11y/aria-unsupported-elements`] | +| `react-a11y-event-has-role` | πŸŒ“ | [`jsx-a11y/no-static-element-interactions`] [2] | +| `react-a11y-image-button-has-alt` | πŸ”Œ | [`jsx-a11y/alt-text`] | +| `react-a11y-img-has-alt` | πŸ”Œ | [`jsx-a11y/alt-text`] | +| `react-a11y-input-elements` | πŸ›‘ | N/A | +| `react-a11y-lang` | πŸ”Œ | [`jsx-a11y/lang`] | +| `react-a11y-meta` | πŸ›‘ | N/A | +| `react-a11y-no-onchange` | πŸ”Œ | [`jsx-a11y/no-onchange`] | +| `react-a11y-props` | πŸ”Œ | [`jsx-a11y/aria-props`] | +| `react-a11y-proptypes` | πŸ”Œ | [`jsx-a11y/aria-proptypes`] | +| `react-a11y-required` | πŸ›‘ | N/A | +| `react-a11y-role-has-required-aria-props` | πŸ”Œ | [`jsx-a11y/role-has-required-aria-props`] | +| `react-a11y-role-supports-aria-props` | πŸ”Œ | [`jsx-a11y/role-supports-aria-props`] | +| `react-a11y-role` | πŸ”Œ | [`jsx-a11y/aria-role`] | +| `react-a11y-tabindex-no-positive` | πŸ”Œ | [`jsx-a11y/tabindex-no-positive`] | +| `react-a11y-titles` | πŸ›‘ | N/A | + +[1] TSLint rule is more strict
+[2] ESLint rule only reports for click handlers + +[prettier]: https://prettier.io + + + +[`adjacent-overload-signatures`]: https://palantir.github.io/tslint/rules/adjacent-overload-signatures +[`ban-ts-ignore`]: https://palantir.github.io/tslint/rules/ban-ts-ignore/ +[`ban-types`]: https://palantir.github.io/tslint/rules/ban-types +[`invalid-void`]: https://palantir.github.io/tslint/rules/invalid-void +[`member-access`]: https://palantir.github.io/tslint/rules/member-access +[`member-ordering`]: https://palantir.github.io/tslint/rules/member-ordering +[`no-any`]: https://palantir.github.io/tslint/rules/no-any +[`no-empty-interface`]: https://palantir.github.io/tslint/rules/no-empty-interface +[`no-import-side-effect`]: https://palantir.github.io/tslint/rules/no-import-side-effect +[`no-inferrable-types`]: https://palantir.github.io/tslint/rules/no-inferrable-types +[`no-internal-module`]: https://palantir.github.io/tslint/rules/no-internal-module +[`no-magic-numbers`]: https://palantir.github.io/tslint/rules/no-magic-numbers +[`no-namespace`]: https://palantir.github.io/tslint/rules/no-namespace +[`no-non-null-assertion`]: https://palantir.github.io/tslint/rules/no-non-null-assertion +[`no-parameter-reassignment`]: https://palantir.github.io/tslint/rules/no-parameter-reassignment +[`no-reference`]: https://palantir.github.io/tslint/rules/no-reference +[`no-unnecessary-type-assertion`]: https://palantir.github.io/tslint/rules/no-unnecessary-type-assertion +[`no-var-requires`]: https://palantir.github.io/tslint/rules/no-var-requires +[`only-arrow-functions`]: https://palantir.github.io/tslint/rules/only-arrow-functions +[`prefer-for-of`]: https://palantir.github.io/tslint/rules/prefer-for-of +[`promise-function-async`]: https://palantir.github.io/tslint/rules/promise-function-async +[`typedef`]: https://palantir.github.io/tslint/rules/typedef +[`typedef-whitespace`]: https://palantir.github.io/tslint/rules/typedef-whitespace +[`unified-signatures`]: https://palantir.github.io/tslint/rules/unified-signatures +[`await-promise`]: https://palantir.github.io/tslint/rules/await-promise +[`ban-comma-operator`]: https://palantir.github.io/tslint/rules/ban-comma-operator +[`ban`]: https://palantir.github.io/tslint/rules/ban +[`curly`]: https://palantir.github.io/tslint/rules/curly +[`forin`]: https://palantir.github.io/tslint/rules/forin +[`function-constructor`]: https://palantir.github.io/tslint/rules/function-constructor +[`import-blacklist`]: https://palantir.github.io/tslint/rules/import-blacklist +[`label-position`]: https://palantir.github.io/tslint/rules/label-position +[`no-arg`]: https://palantir.github.io/tslint/rules/no-arg +[`no-async-without-await`]: https://palantir.github.io/tslint/rules/no-async-without-await +[`no-bitwise`]: https://palantir.github.io/tslint/rules/no-bitwise +[`no-conditional-assignment`]: https://palantir.github.io/tslint/rules/no-conditional-assignment +[`no-console`]: https://palantir.github.io/tslint/rules/no-console +[`no-construct`]: https://palantir.github.io/tslint/rules/no-construct +[`no-debugger`]: https://palantir.github.io/tslint/rules/no-debugger +[`no-duplicate-super`]: https://palantir.github.io/tslint/rules/no-duplicate-super +[`no-duplicate-switch-case`]: https://palantir.github.io/tslint/rules/no-duplicate-switch-case +[`no-duplicate-variable`]: https://palantir.github.io/tslint/rules/no-duplicate-variable +[`no-dynamic-delete`]: https://palantir.github.io/tslint/rules/no-dynamic-delete +[`no-empty`]: https://palantir.github.io/tslint/rules/no-empty +[`no-eval`]: https://palantir.github.io/tslint/rules/no-eval +[`no-floating-promises`]: https://palantir.github.io/tslint/rules/no-floating-promises +[`no-for-in-array`]: https://palantir.github.io/tslint/rules/no-for-in-array +[`no-implicit-dependencies`]: https://palantir.github.io/tslint/rules/no-implicit-dependencies +[`no-inferred-empty-object-type`]: https://palantir.github.io/tslint/rules/no-inferred-empty-object-type +[`no-invalid-template-strings`]: https://palantir.github.io/tslint/rules/no-invalid-template-strings +[`no-invalid-this`]: https://palantir.github.io/tslint/rules/no-invalid-this +[`no-misused-new`]: https://palantir.github.io/tslint/rules/no-misused-new +[`no-null-keyword`]: https://palantir.github.io/tslint/rules/no-null-keyword +[`no-null-undefined-union`]: https://palantir.github.io/tslint/rules/no-null-undefined-union +[`no-object-literal-type-assertion`]: https://palantir.github.io/tslint/rules/no-object-literal-type-assertion +[`no-promise-as-boolean`]: https://palantir.github.io/tslint/rules/no-promise-as-boolean +[`no-restricted-globals`]: https://palantir.github.io/tslint/rules/no-restricted-globals +[`no-return-await`]: https://palantir.github.io/tslint/rules/no-return-await +[`no-shadowed-variable`]: https://palantir.github.io/tslint/rules/no-shadowed-variable +[`no-sparse-arrays`]: https://palantir.github.io/tslint/rules/no-sparse-arrays +[`no-string-literal`]: https://palantir.github.io/tslint/rules/no-string-literal +[`no-string-throw`]: https://palantir.github.io/tslint/rules/no-string-throw +[`no-submodule-imports`]: https://palantir.github.io/tslint/rules/no-submodule-imports +[`no-switch-case-fall-through`]: https://palantir.github.io/tslint/rules/no-switch-case-fall-through +[`no-tautology-expression`]: https://palantir.github.io/tslint/rules/no-tautology-expression +[`no-this-assignment`]: https://palantir.github.io/tslint/rules/no-this-assignment +[`no-unbound-method`]: https://palantir.github.io/tslint/rules/no-unbound-method +[`no-unnecessary-class`]: https://palantir.github.io/tslint/rules/no-unnecessary-class +[`no-unsafe-any`]: https://palantir.github.io/tslint/rules/no-unsafe-any +[`no-unsafe-finally`]: https://palantir.github.io/tslint/rules/no-unsafe-finally +[`no-unused-expression`]: https://palantir.github.io/tslint/rules/no-unused-expression +[`no-unused-variable`]: https://palantir.github.io/tslint/rules/no-unused-variable +[`no-use-before-declare`]: https://palantir.github.io/tslint/rules/no-use-before-declare +[`no-var-keyword`]: https://palantir.github.io/tslint/rules/no-var-keyword +[`no-void-expression`]: https://palantir.github.io/tslint/rules/no-void-expression +[`prefer-conditional-expression`]: https://palantir.github.io/tslint/rules/prefer-conditional-expression +[`prefer-object-spread`]: https://palantir.github.io/tslint/rules/prefer-object-spread +[`radix`]: https://palantir.github.io/tslint/rules/radix +[`restrict-plus-operands`]: https://palantir.github.io/tslint/rules/restrict-plus-operands +[`static-this`]: https://palantir.github.io/tslint/rules/static-this +[`strict-boolean-expressions`]: https://palantir.github.io/tslint/rules/strict-boolean-expressions +[`strict-string-expressions`]: https://palantir.github.io/tslint/rules/strict-string-expressions +[`strict-type-predicates`]: https://palantir.github.io/tslint/rules/strict-type-predicates +[`switch-default`]: https://palantir.github.io/tslint/rules/switch-default +[`triple-equals`]: https://palantir.github.io/tslint/rules/triple-equals +[`typeof-compare`]: https://palantir.github.io/tslint/rules/typeof-compare +[`unnecessary-constructor`]: https://palantir.github.io/tslint/rules/unnecessary-constructor +[`use-default-type-parameter`]: https://palantir.github.io/tslint/rules/use-default-type-parameter +[`use-isnan`]: https://palantir.github.io/tslint/rules/use-isnan +[`cyclomatic-complexity`]: https://palantir.github.io/tslint/rules/cyclomatic-complexity +[`deprecation`]: https://palantir.github.io/tslint/rules/deprecation +[`eofline`]: https://palantir.github.io/tslint/rules/eofline +[`indent`]: https://palantir.github.io/tslint/rules/indent +[`linebreak-style`]: https://palantir.github.io/tslint/rules/linebreak-style +[`max-classes-per-file`]: https://palantir.github.io/tslint/rules/max-classes-per-file +[`max-file-line-count`]: https://palantir.github.io/tslint/rules/max-file-line-count +[`max-line-length`]: https://palantir.github.io/tslint/rules/max-line-length +[`no-default-export`]: https://palantir.github.io/tslint/rules/no-default-export +[`no-default-import`]: https://palantir.github.io/tslint/rules/no-default-import +[`no-duplicate-imports`]: https://palantir.github.io/tslint/rules/no-duplicate-imports +[`no-mergeable-namespace`]: https://palantir.github.io/tslint/rules/no-mergeable-namespace +[`no-require-imports`]: https://palantir.github.io/tslint/rules/no-require-imports +[`object-literal-sort-keys`]: https://palantir.github.io/tslint/rules/object-literal-sort-keys +[`prefer-const`]: https://palantir.github.io/tslint/rules/prefer-const +[`prefer-readonly`]: https://palantir.github.io/tslint/rules/prefer-readonly +[`trailing-comma`]: https://palantir.github.io/tslint/rules/trailing-comma +[`align`]: https://palantir.github.io/tslint/rules/align +[`array-type`]: https://palantir.github.io/tslint/rules/array-type +[`arrow-parens`]: https://palantir.github.io/tslint/rules/arrow-parens +[`arrow-return-shorthand`]: https://palantir.github.io/tslint/rules/arrow-return-shorthand +[`binary-expression-operand-order`]: https://palantir.github.io/tslint/rules/binary-expression-operand-order +[`callable-types`]: https://palantir.github.io/tslint/rules/callable-types +[`class-name`]: https://palantir.github.io/tslint/rules/class-name +[`comment-format`]: https://palantir.github.io/tslint/rules/comment-format +[`comment-type`]: https://palantir.github.io/tslint/rules/comment-type +[`completed-docs`]: https://palantir.github.io/tslint/rules/completed-docs +[`encoding`]: https://palantir.github.io/tslint/rules/encoding +[`file-header`]: https://palantir.github.io/tslint/rules/file-header +[`file-name-casing`]: https://palantir.github.io/tslint/rules/file-name-casing +[`import-spacing`]: https://palantir.github.io/tslint/rules/import-spacing +[`increment-decrement`]: https://palantir.github.io/tslint/rules/increment-decrement +[`interface-name`]: https://palantir.github.io/tslint/rules/interface-name +[`interface-over-type-literal`]: https://palantir.github.io/tslint/rules/interface-over-type-literal +[`jsdoc-format`]: https://palantir.github.io/tslint/rules/jsdoc-format +[`match-default-export-name`]: https://palantir.github.io/tslint/rules/match-default-export-name +[`newline-before-return`]: https://palantir.github.io/tslint/rules/newline-before-return +[`newline-per-chained-call`]: https://palantir.github.io/tslint/rules/newline-per-chained-call +[`new-parens`]: https://palantir.github.io/tslint/rules/new-parens +[`no-angle-bracket-type-assertion`]: https://palantir.github.io/tslint/rules/no-angle-bracket-type-assertion +[`no-boolean-literal-compare`]: https://palantir.github.io/tslint/rules/no-boolean-literal-compare +[`no-consecutive-blank-lines`]: https://palantir.github.io/tslint/rules/no-consecutive-blank-lines +[`no-irregular-whitespace`]: https://palantir.github.io/tslint/rules/no-irregular-whitespace +[`no-parameter-properties`]: https://palantir.github.io/tslint/rules/no-parameter-properties +[`no-redundant-jsdoc`]: https://palantir.github.io/tslint/rules/no-redundant-jsdoc +[`no-reference-import`]: https://palantir.github.io/tslint/rules/no-reference-import +[`no-trailing-whitespace`]: https://palantir.github.io/tslint/rules/no-trailing-whitespace +[`no-unnecessary-callback-wrapper`]: https://palantir.github.io/tslint/rules/no-unnecessary-callback-wrapper +[`no-unnecessary-else`]: https://palantir.github.io/tslint/rules/no-unnecessary-else +[`no-unnecessary-initializer`]: https://palantir.github.io/tslint/rules/no-unnecessary-initializer +[`no-unnecessary-qualifier`]: https://palantir.github.io/tslint/rules/no-unnecessary-qualifier +[`number-literal-format`]: https://palantir.github.io/tslint/rules/number-literal-format +[`object-literal-key-quotes`]: https://palantir.github.io/tslint/rules/object-literal-key-quotes +[`object-literal-shorthand`]: https://palantir.github.io/tslint/rules/object-literal-shorthand +[`one-line`]: https://palantir.github.io/tslint/rules/one-line +[`one-variable-per-declaration`]: https://palantir.github.io/tslint/rules/one-variable-per-declaration +[`ordered-imports`]: https://palantir.github.io/tslint/rules/ordered-imports +[`prefer-function-over-method`]: https://palantir.github.io/tslint/rules/prefer-function-over-method +[`prefer-method-signature`]: https://palantir.github.io/tslint/rules/prefer-method-signature +[`prefer-switch`]: https://palantir.github.io/tslint/rules/prefer-switch +[`prefer-template`]: https://palantir.github.io/tslint/rules/prefer-template +[`prefer-while`]: https://palantir.github.io/tslint/rules/prefer-while +[`quotemark`]: https://palantir.github.io/tslint/rules/quotemark +[`return-undefined`]: https://palantir.github.io/tslint/rules/return-undefined +[`semicolon`]: https://palantir.github.io/tslint/rules/semicolon +[`space-before-function-paren`]: https://palantir.github.io/tslint/rules/space-before-function-paren +[`space-within-parens`]: https://palantir.github.io/tslint/rules/space-within-parens +[`switch-final-break`]: https://palantir.github.io/tslint/rules/switch-final-break +[`type-literal-delimiter`]: https://palantir.github.io/tslint/rules/type-literal-delimiter +[`unnecessary-bind`]: https://palantir.github.io/tslint/rules/unnecessary-bind +[`variable-name`]: https://palantir.github.io/tslint/rules/variable-name +[`whitespace`]: https://palantir.github.io/tslint/rules/whitespace + + + +[no-magic-numbers]: https://eslint.org/docs/rules/no-magic-numbers +[no-param-reassign]: https://eslint.org/docs/rules/no-param-reassign +[no-sequences]: https://eslint.org/docs/rules/no-sequences +[no-restricted-globals]: https://eslint.org/docs/rules/no-restricted-globals +[no-restricted-properties]: https://eslint.org/docs/rules/no-restricted-properties +[no-restricted-syntax]: https://eslint.org/docs/rules/no-restricted-syntax +[curly]: https://eslint.org/docs/rules/curly +[guard-for-in]: https://eslint.org/docs/rules/guard-for-in +[no-new-func]: https://eslint.org/docs/rules/no-new-func +[no-restricted-imports]: https://eslint.org/docs/rules/no-restricted-imports +[no-unused-labels]: https://eslint.org/docs/rules/no-unused-labels +[no-caller]: https://eslint.org/docs/rules/no-caller +[no-bitwise]: https://eslint.org/docs/rules/no-bitwise +[no-cond-assign]: https://eslint.org/docs/rules/no-cond-assign +[no-console]: https://eslint.org/docs/rules/no-console +[no-new-wrappers]: https://eslint.org/docs/rules/no-new-wrappers +[no-debugger]: https://eslint.org/docs/rules/no-debugger +[constructor-super]: https://eslint.org/docs/rules/constructor-super +[no-duplicate-case]: https://eslint.org/docs/rules/no-duplicate-case +[no-redeclare]: https://eslint.org/docs/rules/no-redeclare +[no-empty]: https://eslint.org/docs/rules/no-empty +[no-eval]: https://eslint.org/docs/rules/no-eval +[no-template-curly-in-string]: https://eslint.org/docs/rules/no-template-curly-in-string +[no-invalid-this]: https://eslint.org/docs/rules/no-invalid-this +[no-return-await]: https://eslint.org/docs/rules/no-return-await +[no-shadow]: https://eslint.org/docs/rules/no-shadow +[no-sparse-arrays]: https://eslint.org/docs/rules/no-sparse-arrays +[dot-notation]: https://eslint.org/docs/rules/dot-notation +[no-fallthrough]: https://eslint.org/docs/rules/no-fallthrough +[no-unsafe-finally]: https://eslint.org/docs/rules/no-unsafe-finally +[no-unused-expressions]: https://eslint.org/docs/rules/no-unused-expressions +[no-var]: https://eslint.org/docs/rules/no-var +[prefer-object-spread]: https://eslint.org/docs/rules/prefer-object-spread +[radix]: https://eslint.org/docs/rules/radix +[default-case]: https://eslint.org/docs/rules/default-case +[eqeqeq]: https://eslint.org/docs/rules/eqeqeq +[valid-typeof]: https://eslint.org/docs/rules/valid-typeof +[no-useless-constructor]: https://eslint.org/docs/rules/no-useless-constructor +[use-isnan]: https://eslint.org/docs/rules/use-isnan +[complexity]: https://eslint.org/docs/rules/complexity +[eol-last]: https://eslint.org/docs/rules/eol-last +[linebreak-style]: https://eslint.org/docs/rules/linebreak-style +[max-classes-per-file]: https://eslint.org/docs/rules/max-classes-per-file +[max-lines]: https://eslint.org/docs/rules/max-lines +[max-len]: https://eslint.org/docs/rules/max-len +[sort-keys]: https://eslint.org/docs/rules/sort-keys +[prefer-const]: https://eslint.org/docs/rules/prefer-const +[comma-dangle]: https://eslint.org/docs/rules/comma-dangle +[arrow-parens]: https://eslint.org/docs/rules/arrow-parens +[arrow-body-style]: https://eslint.org/docs/rules/arrow-body-style +[yoda]: https://eslint.org/docs/rules/yoda +[capitalized-comments]: https://eslint.org/docs/rules/capitalized-comments +[spaced-comment]: https://eslint.org/docs/rules/spaced-comment +[no-plusplus]: https://eslint.org/docs/rules/no-plusplus +[valid-jsdoc]: https://eslint.org/docs/rules/valid-jsdoc +[padding-line-between-statements]: https://eslint.org/docs/rules/padding-line-between-statements +[newline-per-chained-call]: https://eslint.org/docs/rules/newline-per-chained-call +[new-parens]: https://eslint.org/docs/rules/new-parens +[no-else-return]: https://eslint.org/docs/rules/no-else-return +[no-multiple-empty-lines]: https://eslint.org/docs/rules/no-multiple-empty-lines +[no-irregular-whitespace]: https://eslint.org/docs/rules/no-irregular-whitespace +[no-trailing-spaces]: https://eslint.org/docs/rules/no-trailing-spaces +[no-undef-init]: https://eslint.org/docs/rules/no-undef-init +[quote-props]: https://eslint.org/docs/rules/quote-props +[object-shorthand]: https://eslint.org/docs/rules/object-shorthand +[brace-style]: https://eslint.org/docs/rules/brace-style +[one-var]: https://eslint.org/docs/rules/one-var +[class-methods-use-this]: https://eslint.org/docs/rules/class-methods-use-this +[prefer-template]: https://eslint.org/docs/rules/prefer-template +[quotes]: https://eslint.org/docs/rules/quotes +[semi]: https://eslint.org/docs/rules/semi +[space-after-function-paren]: https://eslint.org/docs/rules/space-before-function-paren +[space-in-parens]: https://eslint.org/docs/rules/space-in-parens +[no-extra-bind]: https://eslint.org/docs/rules/no-extra-bind +[camelcase]: https://eslint.org/docs/rules/camelcase +[no-underscore-dangle]: https://eslint.org/docs/rules/no-underscore-dangle +[id-blacklist]: https://eslint.org/docs/rules/id-blacklist +[id-match]: https://eslint.org/docs/rules/id-match +[max-statements]: https://eslint.org/docs/rules/max-statements +[no-constant-condition]: https://eslint.org/docs/rules/no-constant-condition +[no-control-regex]: https://eslint.org/docs/rules/no-control-regex +[no-invalid-regexp]: https://eslint.org/docs/rules/no-invalid-regexp +[no-regex-spaces]: https://eslint.org/docs/rules/no-regex-spaces +[no-new-func]: https://eslint.org/docs/rules/no-new-func +[padded-blocks]: https://eslint.org/docs/rules/padded-blocks +[func-style]: https://eslint.org/docs/rules/func-style +[no-multi-str]: https://eslint.org/docs/rules/no-multi-str +[no-octal]: https://eslint.org/docs/rules/no-octal +[no-octal-escape]: https://eslint.org/docs/rules/no-octal-escape +[no-extra-semi]: https://eslint.org/docs/rules/no-extra-semi +[no-with]: https://eslint.org/docs/rules/no-with +[no-warning-comments]: https://eslint.org/docs/rules/no-warning-comments + + + +[`@typescript-eslint/adjacent-overload-signatures`]: https://typescript-eslint.io/rules/adjacent-overload-signatures +[`@typescript-eslint/await-thenable`]: https://typescript-eslint.io/rules/await-thenable +[`@typescript-eslint/ban-types`]: https://typescript-eslint.io/rules/ban-types +[`@typescript-eslint/ban-ts-comment`]: https://typescript-eslint.io/rules/ban-ts-comment +[`@typescript-eslint/consistent-type-assertions`]: https://typescript-eslint.io/rules/consistent-type-assertions +[`@typescript-eslint/consistent-type-definitions`]: https://typescript-eslint.io/rules/consistent-type-definitions +[`@typescript-eslint/explicit-member-accessibility`]: https://typescript-eslint.io/rules/explicit-member-accessibility +[`@typescript-eslint/member-ordering`]: https://typescript-eslint.io/rules/member-ordering +[`@typescript-eslint/method-signature-style`]: https://typescript-eslint.io/rules/method-signature-style +[`@typescript-eslint/no-explicit-any`]: https://typescript-eslint.io/rules/no-explicit-any +[`@typescript-eslint/no-empty-interface`]: https://typescript-eslint.io/rules/no-empty-interface +[`@typescript-eslint/no-implied-eval`]: https://typescript-eslint.io/rules/no-implied-eval +[`@typescript-eslint/no-inferrable-types`]: https://typescript-eslint.io/rules/no-inferrable-types +[`@typescript-eslint/prefer-namespace-keyword`]: https://typescript-eslint.io/rules/prefer-namespace-keyword +[`@typescript-eslint/promise-function-async`]: https://typescript-eslint.io/rules/promise-function-async +[`@typescript-eslint/no-misused-promises`]: https://typescript-eslint.io/rules/no-misused-promises +[`@typescript-eslint/no-namespace`]: https://typescript-eslint.io/rules/no-namespace +[`@typescript-eslint/no-non-null-assertion`]: https://typescript-eslint.io/rules/no-non-null-assertion +[`@typescript-eslint/triple-slash-reference`]: https://typescript-eslint.io/rules/triple-slash-reference +[`@typescript-eslint/unbound-method`]: https://typescript-eslint.io/rules/unbound-method +[`@typescript-eslint/no-unnecessary-type-assertion`]: https://typescript-eslint.io/rules/no-unnecessary-type-assertion +[`@typescript-eslint/no-var-requires`]: https://typescript-eslint.io/rules/no-var-requires +[`@typescript-eslint/type-annotation-spacing`]: https://typescript-eslint.io/rules/type-annotation-spacing +[`@typescript-eslint/typedef`]: https://typescript-eslint.io/rules/typedef +[`@typescript-eslint/unified-signatures`]: https://typescript-eslint.io/rules/unified-signatures +[`@typescript-eslint/no-unnecessary-boolean-literal-compare`]: https://typescript-eslint.io/rules/no-unnecessary-boolean-literal-compare +[`@typescript-eslint/no-misused-new`]: https://typescript-eslint.io/rules/no-misused-new +[`@typescript-eslint/no-this-alias`]: https://typescript-eslint.io/rules/no-this-alias +[`@typescript-eslint/no-throw-literal`]: https://typescript-eslint.io/rules/no-throw-literal +[`@typescript-eslint/no-extraneous-class`]: https://typescript-eslint.io/rules/no-extraneous-class +[`@typescript-eslint/no-unused-vars`]: https://typescript-eslint.io/rules/no-unused-vars +[`@typescript-eslint/no-use-before-define`]: https://typescript-eslint.io/rules/no-use-before-define +[`@typescript-eslint/restrict-plus-operands`]: https://typescript-eslint.io/rules/restrict-plus-operands +[`@typescript-eslint/strict-boolean-expressions`]: https://typescript-eslint.io/rules/strict-boolean-expressions +[`@typescript-eslint/indent`]: https://typescript-eslint.io/rules/indent +[`@typescript-eslint/no-invalid-void-type`]: https://typescript-eslint.io/rules/no-invalid-void-type +[`@typescript-eslint/no-require-imports`]: https://typescript-eslint.io/rules/no-require-imports +[`@typescript-eslint/array-type`]: https://typescript-eslint.io/rules/array-type +[`@typescript-eslint/naming-convention`]: https://typescript-eslint.io/rules/naming-convention +[`@typescript-eslint/interface-name-prefix`]: https://typescript-eslint.io/rules/interface-name-prefix +[`@typescript-eslint/naming-convention`]: https://typescript-eslint.io/rules/naming-convention +[`@typescript-eslint/parameter-properties`]: https://typescript-eslint.io/rules/parameter-properties +[`@typescript-eslint/member-delimiter-style`]: https://typescript-eslint.io/rules/member-delimiter-style +[`@typescript-eslint/prefer-for-of`]: https://typescript-eslint.io/rules/prefer-for-of +[`@typescript-eslint/no-array-constructor`]: https://typescript-eslint.io/rules/no-array-constructor +[`@typescript-eslint/no-dynamic-delete`]: https://typescript-eslint.io/rules/no-dynamic-delete +[`@typescript-eslint/prefer-function-type`]: https://typescript-eslint.io/rules/prefer-function-type +[`@typescript-eslint/prefer-readonly`]: https://typescript-eslint.io/rules/prefer-readonly +[`@typescript-eslint/require-await`]: https://typescript-eslint.io/rules/require-await +[`@typescript-eslint/no-for-in-array`]: https://typescript-eslint.io/rules/no-for-in-array +[`@typescript-eslint/no-unnecessary-qualifier`]: https://typescript-eslint.io/rules/no-unnecessary-qualifier +[`@typescript-eslint/no-unnecessary-type-arguments`]: https://typescript-eslint.io/rules/no-unnecessary-type-arguments +[`@typescript-eslint/semi`]: https://typescript-eslint.io/rules/semi +[`@typescript-eslint/no-floating-promises`]: https://typescript-eslint.io/rules/no-floating-promises +[`@typescript-eslint/no-magic-numbers`]: https://typescript-eslint.io/rules/no-magic-numbers +[`@typescript-eslint/no-unsafe-member-access`]: https://typescript-eslint.io/rules/no-unsafe-member-access +[`@typescript-eslint/restrict-template-expressions`]: https://typescript-eslint.io/rules/restrict-template-expressions +[`@typescript-eslint/no-confusing-void-expression`]: https://typescript-eslint.io/rules/no-confusing-void-expression + + + +[plugin:import]: https://github.com/benmosher/eslint-plugin-import +[`import/no-unassigned-import`]: https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-unassigned-import.md +[`import/no-extraneous-dependencies`]: https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-extraneous-dependencies.md +[`import/no-internal-modules`]: https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-internal-modules.md +[`import/no-deprecated`]: https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-deprecated.md +[`import/no-default-export`]: https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-default-export.md +[`import/no-duplicates`]: https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-duplicates.md +[`import/order`]: https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/order.md + + + +[`react/no-danger`]: https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-danger.md +[`react/jsx-curly-spacing`]: https://github.com/yannickcr/eslint-plugin-react/blob/HEAD/docs/rules/jsx-curly-spacing.md +[`react/jsx-no-target-blank`]: https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-target-blank.md +[`react/no-unused-state`]: https://github.com/yannickcr/eslint-plugin-react/blob/HEAD/docs/rules/no-unused-state.md + + + +[`jsx-a11y/anchor-is-valid`]: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/anchor-is-valid.md +[`jsx-a11y/aria-unsupported-elements`]: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-unsupported-elements.md +[`jsx-a11y/no-static-element-interactions`]: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-static-element-interactions.md +[`jsx-a11y/alt-text`]: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/alt-text.md +[`jsx-a11y/html-has-lang`]: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/html-has-lang.md +[`jsx-a11y/lang`]: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/lang.md +[`jsx-a11y/no-onchange`]: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-onchange.md +[`jsx-a11y/aria-props`]: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-props.md +[`jsx-a11y/aria-proptypes`]: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-proptypes.md +[`jsx-a11y/role-has-required-aria-props`]: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/role-has-required-aria-props.md +[`jsx-a11y/role-supports-aria-props`]: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/role-supports-aria-props.md +[`jsx-a11y/aria-role`]: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-role.md +[`jsx-a11y/tabindex-no-positive`]: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/tabindex-no-positive.md + + + +[`security/detect-non-literal-fs-filename`]: https://github.com/nodesecurity/eslint-plugin-security#detect-non-literal-fs-filename +[`security/detect-non-literal-require`]: https://github.com/nodesecurity/eslint-plugin-security#detect-non-literal-require +[`security/detect-possible-timing-attacks`]: https://github.com/nodesecurity/eslint-plugin-security#detect-possible-timing-attacks + + + +[plugin:jsdoc]: https://github.com/gajus/eslint-plugin-jsdoc +[`jsdoc/require-jsdoc`]: https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-jsdoc +[`jsdoc/no-types`]: https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-no-types + + + +[`@microsoft/sdl/no-cookies`]: https://github.com/microsoft/eslint-plugin-sdl/blob/main/docs/rules/no-cookies.md +[`@microsoft/sdl/no-document-domain`]: https://github.com/microsoft/eslint-plugin-sdl/blob/main/docs/rules/no-document-domain.md +[`@microsoft/sdl/no-document-write`]: https://github.com/microsoft/eslint-plugin-sdl/blob/main/docs/rules/no-document-write.md +[`@microsoft/sdl/no-html-method`]: https://github.com/microsoft/eslint-plugin-sdl/blob/main/docs/rules/no-html-method.md +[`@microsoft/sdl/no-inner-html`]: https://github.com/microsoft/eslint-plugin-sdl/blob/main/docs/rules/no-inner-html.md +[`@microsoft/sdl/no-insecure-random`]: https://github.com/microsoft/eslint-plugin-sdl/blob/main/docs/rules/no-insecure-random.md +[`@microsoft/sdl/no-insecure-url`]: https://github.com/microsoft/eslint-plugin-sdl/blob/main/docs/rules/no-insecure-url.md +[`@microsoft/sdl/no-msapp-exec-unsafe`]: https://github.com/microsoft/eslint-plugin-sdl/blob/main/docs/rules/no-msapp-exec-unsafe.md +[`@microsoft/sdl/no-winjs-html-unsafe`]: https://github.com/microsoft/eslint-plugin-sdl/blob/main/docs/rules/no-winjs-html-unsafe.md +[`@microsoft/sdl/react-iframe-missing-sandbox`]: https://github.com/microsoft/eslint-plugin-sdl/blob/main/docs/rules/react-iframe-missing-sandbox.md + + + +[`prefer-arrow/prefer-arrow-functions`]: https://github.com/TristonJ/eslint-plugin-prefer-arrow +[plugin:promise]: https://github.com/xjamundx/eslint-plugin-promise +[plugin:header]: https://github.com/Stuk/eslint-plugin-header +[plugin:file-header]: https://github.com/Sekhmet/eslint-plugin-file-header +[plugin:compat]: https://github.com/amilajack/eslint-plugin-compat +[`no-null/no-null`]: https://github.com/nene/eslint-plugin-no-null +[`unicorn/filename-case`]: https://github.com/sindresorhus/eslint-plugin-unicorn/blob/master/docs/rules/filename-case.md +[`jest/no-focused-tests`]: https://github.com/jest-community/eslint-plugin-jest/blob/main/docs/rules/no-focused-tests.md +[`jsx-a11y/heading-has-content`]: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/heading-has-content.md +[`lodash/chaining`]: https://github.com/wix/eslint-plugin-lodash/blob/master/docs/rules/chaining.md +[`deprecation/deprecation`]: https://github.com/gund/eslint-plugin-deprecation +[`desktop/insecure-random`]: https://github.com/desktop/desktop/blob/development/eslint-rules/insecure-random.js diff --git a/packages/eslint-plugin/docs/rules/TEMPLATE.md b/packages/eslint-plugin/docs/rules/TEMPLATE.md index 7528ad501a31..a49ed54ac02a 100644 --- a/packages/eslint-plugin/docs/rules/TEMPLATE.md +++ b/packages/eslint-plugin/docs/rules/TEMPLATE.md @@ -1,6 +1,6 @@ -# `your-rule-name` - -Your rule description here. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/your-rule-name** for documentation. ## Rule Details diff --git a/packages/eslint-plugin/docs/rules/adjacent-overload-signatures.md b/packages/eslint-plugin/docs/rules/adjacent-overload-signatures.md index a30dfe06142e..57677bd4ac1f 100644 --- a/packages/eslint-plugin/docs/rules/adjacent-overload-signatures.md +++ b/packages/eslint-plugin/docs/rules/adjacent-overload-signatures.md @@ -1,6 +1,6 @@ -# `adjacent-overload-signatures` - -Requires that member overloads be consecutive. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/adjacent-overload-signatures** for documentation. Grouping overloaded members together can improve readability of the code. diff --git a/packages/eslint-plugin/docs/rules/array-type.md b/packages/eslint-plugin/docs/rules/array-type.md index 1e0ea89327dc..9a9ac0985bc3 100644 --- a/packages/eslint-plugin/docs/rules/array-type.md +++ b/packages/eslint-plugin/docs/rules/array-type.md @@ -1,6 +1,6 @@ -# `array-type` - -Requires using either `T[]` or `Array` for arrays. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/array-type** for documentation. Using the same style for array definitions across your codebase makes it easier for your developers to read and understand the types. diff --git a/packages/eslint-plugin/docs/rules/await-thenable.md b/packages/eslint-plugin/docs/rules/await-thenable.md index 4a2398719275..d0d3d5f7d521 100644 --- a/packages/eslint-plugin/docs/rules/await-thenable.md +++ b/packages/eslint-plugin/docs/rules/await-thenable.md @@ -1,6 +1,6 @@ -# `await-thenable` - -Disallows awaiting a value that is not a Thenable. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/await-thenable** for documentation. This rule disallows awaiting a value that is not a "Thenable" (an object which has `then` method, such as a Promise). While it is valid JavaScript to await a non-`Promise`-like value (it will resolve immediately), this pattern is often a programmer error, such as forgetting to add parenthesis to call a function that returns a Promise. diff --git a/packages/eslint-plugin/docs/rules/ban-ts-comment.md b/packages/eslint-plugin/docs/rules/ban-ts-comment.md index 2e62bfcd4a80..f560c55ff054 100644 --- a/packages/eslint-plugin/docs/rules/ban-ts-comment.md +++ b/packages/eslint-plugin/docs/rules/ban-ts-comment.md @@ -1,6 +1,6 @@ -# `ban-ts-comment` - -Disallows `@ts-` comments or requires descriptions after directive. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/ban-ts-comment** for documentation. TypeScript provides several directive comments that can be used to alter how it processes files. Using these to suppress TypeScript Compiler Errors reduces the effectiveness of TypeScript overall. diff --git a/packages/eslint-plugin/docs/rules/ban-tslint-comment.md b/packages/eslint-plugin/docs/rules/ban-tslint-comment.md index b89e9929167a..3e5789bc005b 100644 --- a/packages/eslint-plugin/docs/rules/ban-tslint-comment.md +++ b/packages/eslint-plugin/docs/rules/ban-tslint-comment.md @@ -1,6 +1,6 @@ -# `ban-tslint-comment` - -Disallows `// tslint:` comments. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/ban-tslint-comment** for documentation. Useful when migrating from TSLint to ESLint. Once TSLint has been removed, this rule helps locate TSLint annotations (e.g. `// tslint:disable`). diff --git a/packages/eslint-plugin/docs/rules/ban-types.md b/packages/eslint-plugin/docs/rules/ban-types.md index b5dc1b0e33cd..256b12372fe7 100644 --- a/packages/eslint-plugin/docs/rules/ban-types.md +++ b/packages/eslint-plugin/docs/rules/ban-types.md @@ -1,6 +1,6 @@ -# `ban-types` - -Disallows certain types. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/ban-types** for documentation. Some builtin types have aliases, some types are considered dangerous or harmful. It's often a good idea to ban certain types to help with consistency and safety. diff --git a/packages/eslint-plugin/docs/rules/brace-style.md b/packages/eslint-plugin/docs/rules/brace-style.md index a21884184608..923a841fcbde 100644 --- a/packages/eslint-plugin/docs/rules/brace-style.md +++ b/packages/eslint-plugin/docs/rules/brace-style.md @@ -1,6 +1,6 @@ -# `brace-style` - -Enforces consistent brace style for blocks. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/brace-style** for documentation. ## Rule Details 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 afbdc96fc187..5b577e16136f 100644 --- a/packages/eslint-plugin/docs/rules/class-literal-property-style.md +++ b/packages/eslint-plugin/docs/rules/class-literal-property-style.md @@ -1,6 +1,6 @@ -# `class-literal-property-style` - -Enforces that literals on classes are exposed in a consistent style. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/class-literal-property-style** for documentation. When writing TypeScript applications, it's typically safe to store literal values on classes using fields with the `readonly` modifier to prevent them from being reassigned. When writing TypeScript libraries that could be used by JavaScript users however, it's typically safer to expose these literals using `getter`s, since the `readonly` modifier is enforced at compile type. diff --git a/packages/eslint-plugin/docs/rules/comma-dangle.md b/packages/eslint-plugin/docs/rules/comma-dangle.md index 9c827252f3b9..0af19151a0eb 100644 --- a/packages/eslint-plugin/docs/rules/comma-dangle.md +++ b/packages/eslint-plugin/docs/rules/comma-dangle.md @@ -1,6 +1,6 @@ -# `comma-dangle` - -Requires or disallows trailing commas. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/comma-dangle** for documentation. ## Rule Details diff --git a/packages/eslint-plugin/docs/rules/comma-spacing.md b/packages/eslint-plugin/docs/rules/comma-spacing.md index 7fa6056759dc..28ea99602d90 100644 --- a/packages/eslint-plugin/docs/rules/comma-spacing.md +++ b/packages/eslint-plugin/docs/rules/comma-spacing.md @@ -1,6 +1,6 @@ -# `comma-spacing` - -Enforces consistent spacing before and after commas. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/comma-spacing** for documentation. ## Rule Details diff --git a/packages/eslint-plugin/docs/rules/consistent-generic-constructors.md b/packages/eslint-plugin/docs/rules/consistent-generic-constructors.md index db717dbcbd3d..e62ba44bbb91 100644 --- a/packages/eslint-plugin/docs/rules/consistent-generic-constructors.md +++ b/packages/eslint-plugin/docs/rules/consistent-generic-constructors.md @@ -1,6 +1,6 @@ -# `consistent-generic-constructors` - -Enforces specifying generic type arguments on type annotation or constructor name of a constructor call. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/consistent-generic-constructors** for documentation. When constructing a generic class, you can specify the type arguments on either the left-hand side (as a type annotation) or the right-hand side (as part of the constructor call): 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 f61a4f68fdde..56c22fec4db7 100644 --- a/packages/eslint-plugin/docs/rules/consistent-indexed-object-style.md +++ b/packages/eslint-plugin/docs/rules/consistent-indexed-object-style.md @@ -1,6 +1,6 @@ -# `consistent-indexed-object-style` - -Requires or disallows the `Record` type. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/consistent-indexed-object-style** for documentation. TypeScript supports defining object show keys can be flexible using an index signature. TypeScript also has a builtin type named `Record` to create an empty object defining only an index signature. For example, the following types are equal: diff --git a/packages/eslint-plugin/docs/rules/consistent-type-assertions.md b/packages/eslint-plugin/docs/rules/consistent-type-assertions.md index 7e1d4d0487c8..bb624e83b9d6 100644 --- a/packages/eslint-plugin/docs/rules/consistent-type-assertions.md +++ b/packages/eslint-plugin/docs/rules/consistent-type-assertions.md @@ -1,6 +1,6 @@ -# `consistent-type-assertions` - -Enforces consistent usage of type assertions. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/consistent-type-assertions** for documentation. ## Rule Details diff --git a/packages/eslint-plugin/docs/rules/consistent-type-definitions.md b/packages/eslint-plugin/docs/rules/consistent-type-definitions.md index 1df12bcde43f..625bb7ba4935 100644 --- a/packages/eslint-plugin/docs/rules/consistent-type-definitions.md +++ b/packages/eslint-plugin/docs/rules/consistent-type-definitions.md @@ -1,6 +1,6 @@ -# `consistent-type-definitions` - -Enforces type definitions to consistently use either `interface` or `type`. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/consistent-type-definitions** for documentation. There are two ways to define a type. diff --git a/packages/eslint-plugin/docs/rules/consistent-type-exports.md b/packages/eslint-plugin/docs/rules/consistent-type-exports.md index bd10a616261c..5383a1225b10 100644 --- a/packages/eslint-plugin/docs/rules/consistent-type-exports.md +++ b/packages/eslint-plugin/docs/rules/consistent-type-exports.md @@ -1,6 +1,6 @@ -# `consistent-type-exports` - -Enforces consistent usage of type exports. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/consistent-type-exports** for documentation. TypeScript 3.8 added support for type-only exports. diff --git a/packages/eslint-plugin/docs/rules/consistent-type-imports.md b/packages/eslint-plugin/docs/rules/consistent-type-imports.md index 47022b04ec57..be63fff55516 100644 --- a/packages/eslint-plugin/docs/rules/consistent-type-imports.md +++ b/packages/eslint-plugin/docs/rules/consistent-type-imports.md @@ -1,6 +1,6 @@ -# `consistent-type-imports` - -Enforces consistent usage of type imports. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/consistent-type-imports** for documentation. TypeScript 3.8 added support for type-only imports. Type-only imports allow you to specify that an import can only be used in a type location, allowing certain optimizations within compilers. diff --git a/packages/eslint-plugin/docs/rules/default-param-last.md b/packages/eslint-plugin/docs/rules/default-param-last.md index 5db33411d1d5..3de8f8c8cd7a 100644 --- a/packages/eslint-plugin/docs/rules/default-param-last.md +++ b/packages/eslint-plugin/docs/rules/default-param-last.md @@ -1,6 +1,6 @@ -# `default-param-last` - -Enforces default parameters to be last. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/default-param-last** for documentation. ## Rule Details diff --git a/packages/eslint-plugin/docs/rules/dot-notation.md b/packages/eslint-plugin/docs/rules/dot-notation.md index 414170416846..e0c7b390e5ad 100644 --- a/packages/eslint-plugin/docs/rules/dot-notation.md +++ b/packages/eslint-plugin/docs/rules/dot-notation.md @@ -1,6 +1,6 @@ -# `dot-notation` - -Enforces dot notation whenever possible. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/dot-notation** for documentation. ## Rule Details 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 9e3ff78a3665..d42e793a5cb2 100644 --- a/packages/eslint-plugin/docs/rules/explicit-function-return-type.md +++ b/packages/eslint-plugin/docs/rules/explicit-function-return-type.md @@ -1,6 +1,6 @@ -# `explicit-function-return-type` - -Requires explicit return types on functions and class methods. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/explicit-function-return-type** for documentation. Explicit types for function return values makes it clear to any calling code what type is returned. This ensures that the return value is assigned to a variable of the correct type; or in the case diff --git a/packages/eslint-plugin/docs/rules/explicit-member-accessibility.md b/packages/eslint-plugin/docs/rules/explicit-member-accessibility.md index 4b41a1327eda..98f297000bd5 100644 --- a/packages/eslint-plugin/docs/rules/explicit-member-accessibility.md +++ b/packages/eslint-plugin/docs/rules/explicit-member-accessibility.md @@ -1,6 +1,6 @@ -# `explicit-member-accessibility` - -Requires explicit accessibility modifiers on class properties and methods. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/explicit-member-accessibility** for documentation. Leaving off accessibility modifier and making everything public can make your interface hard to use by others. 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 b25350b60b97..9aa84b23a7c7 100644 --- a/packages/eslint-plugin/docs/rules/explicit-module-boundary-types.md +++ b/packages/eslint-plugin/docs/rules/explicit-module-boundary-types.md @@ -1,6 +1,6 @@ -# `explicit-module-boundary-types` - -Requires explicit return and argument types on exported functions' and classes' public class methods. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/explicit-module-boundary-types** for documentation. Explicit types for function return values and arguments makes it clear to any calling code what is the module boundary's input and output. diff --git a/packages/eslint-plugin/docs/rules/func-call-spacing.md b/packages/eslint-plugin/docs/rules/func-call-spacing.md index 88b73e2eda25..315e53882409 100644 --- a/packages/eslint-plugin/docs/rules/func-call-spacing.md +++ b/packages/eslint-plugin/docs/rules/func-call-spacing.md @@ -1,6 +1,6 @@ -# `func-call-spacing` - -Requires or disallows spacing between function identifiers and their invocations. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/func-call-spacing** for documentation. ## Rule Details diff --git a/packages/eslint-plugin/docs/rules/indent.md b/packages/eslint-plugin/docs/rules/indent.md index 5d732a305bf4..063087231a5d 100644 --- a/packages/eslint-plugin/docs/rules/indent.md +++ b/packages/eslint-plugin/docs/rules/indent.md @@ -1,6 +1,6 @@ -# `indent` - -Enforces consistent indentation. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/indent** for documentation. ## Warning diff --git a/packages/eslint-plugin/docs/rules/init-declarations.md b/packages/eslint-plugin/docs/rules/init-declarations.md index 6a4ce4786512..3569bd70602a 100644 --- a/packages/eslint-plugin/docs/rules/init-declarations.md +++ b/packages/eslint-plugin/docs/rules/init-declarations.md @@ -1,6 +1,6 @@ -# `init-declarations` - -Requires or disallows initialization in variable declarations. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/init-declarations** for documentation. ## Rule Details diff --git a/packages/eslint-plugin/docs/rules/keyword-spacing.md b/packages/eslint-plugin/docs/rules/keyword-spacing.md index 4b9b386b940f..6bf0de5e1870 100644 --- a/packages/eslint-plugin/docs/rules/keyword-spacing.md +++ b/packages/eslint-plugin/docs/rules/keyword-spacing.md @@ -1,6 +1,6 @@ -# `keyword-spacing` - -Enforces consistent spacing before and after keywords. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/keyword-spacing** for documentation. ## Rule Details diff --git a/packages/eslint-plugin/docs/rules/lines-between-class-members.md b/packages/eslint-plugin/docs/rules/lines-between-class-members.md index 8a68abe9cda1..2d9de3a73ce7 100644 --- a/packages/eslint-plugin/docs/rules/lines-between-class-members.md +++ b/packages/eslint-plugin/docs/rules/lines-between-class-members.md @@ -1,6 +1,6 @@ -# `lines-between-class-members` - -Requires or disallows an empty line between class members. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/lines-between-class-members** for documentation. This rule improves readability by enforcing lines between class members. It will not check empty lines before the first member and after the last member. This rule require or disallow an empty line between class members. diff --git a/packages/eslint-plugin/docs/rules/member-delimiter-style.md b/packages/eslint-plugin/docs/rules/member-delimiter-style.md index 858d3777d069..3935222e1c75 100644 --- a/packages/eslint-plugin/docs/rules/member-delimiter-style.md +++ b/packages/eslint-plugin/docs/rules/member-delimiter-style.md @@ -1,6 +1,6 @@ -# `member-delimiter-style` - -Requires a specific member delimiter style for interfaces and type literals. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/member-delimiter-style** for documentation. Enforces a consistent member delimiter style in interfaces and type literals. There are three member delimiter styles primarily used in TypeScript: diff --git a/packages/eslint-plugin/docs/rules/member-ordering.md b/packages/eslint-plugin/docs/rules/member-ordering.md index aacc062008f9..5dd18d6beec3 100644 --- a/packages/eslint-plugin/docs/rules/member-ordering.md +++ b/packages/eslint-plugin/docs/rules/member-ordering.md @@ -1,6 +1,6 @@ -# `member-ordering` - -Requires a consistent member declaration order. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/member-ordering** for documentation. A consistent ordering of fields, methods and constructors can make interfaces, type literals, classes and class expressions easier to read, navigate, and edit. diff --git a/packages/eslint-plugin/docs/rules/method-signature-style.md b/packages/eslint-plugin/docs/rules/method-signature-style.md index 53a6d3e17a02..ad947db32610 100644 --- a/packages/eslint-plugin/docs/rules/method-signature-style.md +++ b/packages/eslint-plugin/docs/rules/method-signature-style.md @@ -1,6 +1,6 @@ -# `method-signature-style` - -Enforces using a particular method signature syntax. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/method-signature-style** for documentation. There are two ways to define an object/interface function property. diff --git a/packages/eslint-plugin/docs/rules/naming-convention.md b/packages/eslint-plugin/docs/rules/naming-convention.md index 9032119ca40d..08da84d15b47 100644 --- a/packages/eslint-plugin/docs/rules/naming-convention.md +++ b/packages/eslint-plugin/docs/rules/naming-convention.md @@ -1,6 +1,6 @@ -# `naming-convention` - -Enforces naming conventions for everything across a codebase. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/naming-convention** for documentation. Enforcing naming conventions helps keep the codebase consistent, and reduces overhead when thinking about how to name a variable. Additionally, a well-designed style guide can help communicate intent, such as by enforcing all private properties begin with an `_`, and all global-level constants are written in `UPPER_CASE`. diff --git a/packages/eslint-plugin/docs/rules/no-array-constructor.md b/packages/eslint-plugin/docs/rules/no-array-constructor.md index 01fd843caf16..6251ddf53dc8 100644 --- a/packages/eslint-plugin/docs/rules/no-array-constructor.md +++ b/packages/eslint-plugin/docs/rules/no-array-constructor.md @@ -1,6 +1,6 @@ -# `no-array-constructor` - -Disallows generic `Array` constructors. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-array-constructor** for documentation. ## Rule Details 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 1e5cd41c94aa..8e64d5eac789 100644 --- a/packages/eslint-plugin/docs/rules/no-base-to-string.md +++ b/packages/eslint-plugin/docs/rules/no-base-to-string.md @@ -1,4 +1,6 @@ -# `no-base-to-string` +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-base-to-string** for documentation. Requires `.toString()` to only be called on objects which provide useful information when stringified. diff --git a/packages/eslint-plugin/docs/rules/no-confusing-non-null-assertion.md b/packages/eslint-plugin/docs/rules/no-confusing-non-null-assertion.md index 77d11f68d211..f77d111bc8c8 100644 --- a/packages/eslint-plugin/docs/rules/no-confusing-non-null-assertion.md +++ b/packages/eslint-plugin/docs/rules/no-confusing-non-null-assertion.md @@ -1,6 +1,6 @@ -# `no-confusing-non-null-assertion` - -Disallows non-null assertion in locations that may be confusing. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-confusing-non-null-assertion** for documentation. ## Rule Details 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 8589e65d4c19..b4d1503d3063 100644 --- a/packages/eslint-plugin/docs/rules/no-confusing-void-expression.md +++ b/packages/eslint-plugin/docs/rules/no-confusing-void-expression.md @@ -1,6 +1,6 @@ -# `no-confusing-void-expression` - -Requires expressions of type void to appear in statement position. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-confusing-void-expression** for documentation. Returning the results of an expression whose type is void can be misleading. Attempting to do so is likely a symptom of expecting a different return type from a function. diff --git a/packages/eslint-plugin/docs/rules/no-dupe-class-members.md b/packages/eslint-plugin/docs/rules/no-dupe-class-members.md index e31b8548c660..32e6c5dfdfba 100644 --- a/packages/eslint-plugin/docs/rules/no-dupe-class-members.md +++ b/packages/eslint-plugin/docs/rules/no-dupe-class-members.md @@ -1,6 +1,6 @@ -# `no-dupe-class-members` - -Disallows duplicate class members. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-dupe-class-members** for documentation. ## Rule Details 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 6b69d540c55f..3e284d3eec62 100644 --- a/packages/eslint-plugin/docs/rules/no-duplicate-enum-values.md +++ b/packages/eslint-plugin/docs/rules/no-duplicate-enum-values.md @@ -1,6 +1,6 @@ -# `no-duplicate-enum-values` - -Disallows duplicate enum member values. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-duplicate-enum-values** for documentation. Although TypeScript supports duplicate enum member values, people usually expect members to have unique values within the same enum. Duplicate values can lead to bugs that are hard to track down. diff --git a/packages/eslint-plugin/docs/rules/no-duplicate-imports.md b/packages/eslint-plugin/docs/rules/no-duplicate-imports.md index 90ab3da41235..613043bedb4f 100644 --- a/packages/eslint-plugin/docs/rules/no-duplicate-imports.md +++ b/packages/eslint-plugin/docs/rules/no-duplicate-imports.md @@ -1,6 +1,6 @@ -# `no-duplicate-imports` - -Disallows duplicate imports. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-duplicate-imports** for documentation. ## DEPRECATED diff --git a/packages/eslint-plugin/docs/rules/no-dynamic-delete.md b/packages/eslint-plugin/docs/rules/no-dynamic-delete.md index e0c590a9de97..7c6090f812f8 100644 --- a/packages/eslint-plugin/docs/rules/no-dynamic-delete.md +++ b/packages/eslint-plugin/docs/rules/no-dynamic-delete.md @@ -1,6 +1,6 @@ -# `no-dynamic-delete` - -Disallows using the `delete` operator on computed key expressions. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-dynamic-delete** for documentation. Deleting dynamically computed keys can be dangerous and in some cases not well optimized. diff --git a/packages/eslint-plugin/docs/rules/no-empty-function.md b/packages/eslint-plugin/docs/rules/no-empty-function.md index e23cc10bdd43..121db4ff8786 100644 --- a/packages/eslint-plugin/docs/rules/no-empty-function.md +++ b/packages/eslint-plugin/docs/rules/no-empty-function.md @@ -1,6 +1,6 @@ -# `no-empty-function` - -Disallows empty functions. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-empty-function** for documentation. ## Rule Details diff --git a/packages/eslint-plugin/docs/rules/no-empty-interface.md b/packages/eslint-plugin/docs/rules/no-empty-interface.md index c9e36a528b1c..beed5a85ecc7 100644 --- a/packages/eslint-plugin/docs/rules/no-empty-interface.md +++ b/packages/eslint-plugin/docs/rules/no-empty-interface.md @@ -1,6 +1,6 @@ -# `no-empty-interface` - -Disallows the declaration of empty interfaces. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-empty-interface** for documentation. An empty interface is equivalent to its supertype. If the interface does not implement a supertype, then the interface is equivalent to an empty object (`{}`). In both cases it can be omitted. diff --git a/packages/eslint-plugin/docs/rules/no-explicit-any.md b/packages/eslint-plugin/docs/rules/no-explicit-any.md index ebf043104986..f8e42896dbd4 100644 --- a/packages/eslint-plugin/docs/rules/no-explicit-any.md +++ b/packages/eslint-plugin/docs/rules/no-explicit-any.md @@ -1,6 +1,6 @@ -# `no-explicit-any` - -Disallows the `any` type. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-explicit-any** for documentation. Using the `any` type defeats the purpose of using TypeScript. When `any` is used, all compiler type checks around that value are ignored. 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 43cfacf756ff..6c7068b693b0 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 @@ -1,6 +1,6 @@ -# `no-extra-non-null-assertion` - -Disallows extra non-null assertion. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-extra-non-null-assertion** for documentation. ## Rule Details diff --git a/packages/eslint-plugin/docs/rules/no-extra-parens.md b/packages/eslint-plugin/docs/rules/no-extra-parens.md index f123b70d1417..8bd5ac2c7d68 100644 --- a/packages/eslint-plugin/docs/rules/no-extra-parens.md +++ b/packages/eslint-plugin/docs/rules/no-extra-parens.md @@ -1,6 +1,6 @@ -# `no-extra-parens` - -Disallows unnecessary parentheses. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-extra-parens** for documentation. ## Rule Details diff --git a/packages/eslint-plugin/docs/rules/no-extra-semi.md b/packages/eslint-plugin/docs/rules/no-extra-semi.md index b0649081b5c3..0b94c91de590 100644 --- a/packages/eslint-plugin/docs/rules/no-extra-semi.md +++ b/packages/eslint-plugin/docs/rules/no-extra-semi.md @@ -1,6 +1,6 @@ -# `no-extra-semi` - -Disallows unnecessary semicolons. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-extra-semi** for documentation. ## Rule Details diff --git a/packages/eslint-plugin/docs/rules/no-extraneous-class.md b/packages/eslint-plugin/docs/rules/no-extraneous-class.md index e1697254ef91..fa990f2cebfd 100644 --- a/packages/eslint-plugin/docs/rules/no-extraneous-class.md +++ b/packages/eslint-plugin/docs/rules/no-extraneous-class.md @@ -1,6 +1,6 @@ -# `no-extraneous-class` - -Disallows classes used as namespaces. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-extraneous-class** for documentation. This rule warns when a class has no non-static members, such as for a class used exclusively as a static namespace. diff --git a/packages/eslint-plugin/docs/rules/no-floating-promises.md b/packages/eslint-plugin/docs/rules/no-floating-promises.md index 1df8ea23c72b..45fddc3c6219 100644 --- a/packages/eslint-plugin/docs/rules/no-floating-promises.md +++ b/packages/eslint-plugin/docs/rules/no-floating-promises.md @@ -1,6 +1,6 @@ -# `no-floating-promises` - -Requires Promise-like statements to be handled appropriately. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-floating-promises** for documentation. A "floating" Promise is one that is created without any code set up to handle any errors it might throw. 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 bcc51aa1660a..29d0c2548a48 100644 --- a/packages/eslint-plugin/docs/rules/no-for-in-array.md +++ b/packages/eslint-plugin/docs/rules/no-for-in-array.md @@ -1,6 +1,6 @@ -# `no-for-in-array` - -Disallows iterating over an array with a for-in loop. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-for-in-array** for documentation. This rule prohibits iterating over an array with a for-in loop. diff --git a/packages/eslint-plugin/docs/rules/no-implicit-any-catch.md b/packages/eslint-plugin/docs/rules/no-implicit-any-catch.md index 40530896835c..97afdfd57877 100644 --- a/packages/eslint-plugin/docs/rules/no-implicit-any-catch.md +++ b/packages/eslint-plugin/docs/rules/no-implicit-any-catch.md @@ -1,6 +1,6 @@ -# `no-implicit-any-catch` - -Disallows usage of the implicit `any` type in catch clauses. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-implicit-any-catch** for documentation. TypeScript 4.0 added support for adding an explicit `any` or `unknown` type annotation on a catch clause variable. diff --git a/packages/eslint-plugin/docs/rules/no-implied-eval.md b/packages/eslint-plugin/docs/rules/no-implied-eval.md index d39a6f70609f..5cd9a9113a5d 100644 --- a/packages/eslint-plugin/docs/rules/no-implied-eval.md +++ b/packages/eslint-plugin/docs/rules/no-implied-eval.md @@ -1,6 +1,6 @@ -# `no-implied-eval` - -Disallows the use of `eval()`-like methods. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-implied-eval** for documentation. It's considered a good practice to avoid using `eval()`. There are security and performance implications involved with doing so, which is why many linters recommend disallowing `eval()`. However, there are some other ways to pass a string and have it interpreted as JavaScript code that have similar concerns. diff --git a/packages/eslint-plugin/docs/rules/no-inferrable-types.md b/packages/eslint-plugin/docs/rules/no-inferrable-types.md index 137d6c558bef..73fcfd7ae520 100644 --- a/packages/eslint-plugin/docs/rules/no-inferrable-types.md +++ b/packages/eslint-plugin/docs/rules/no-inferrable-types.md @@ -1,6 +1,6 @@ -# `no-inferrable-types` - -Disallows explicit type declarations for variables or parameters initialized to a number, string, or boolean. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-inferrable-types** for documentation. Explicit types where they can be easily inferred may add unnecessary verbosity. diff --git a/packages/eslint-plugin/docs/rules/no-invalid-this.md b/packages/eslint-plugin/docs/rules/no-invalid-this.md index 5061e60559d1..22e7de7260bf 100644 --- a/packages/eslint-plugin/docs/rules/no-invalid-this.md +++ b/packages/eslint-plugin/docs/rules/no-invalid-this.md @@ -1,6 +1,6 @@ -# `no-invalid-this` - -Disallows `this` keywords outside of classes or class-like objects. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-invalid-this** for documentation. ## Rule Details 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 928fc6152970..0b4f93385225 100644 --- a/packages/eslint-plugin/docs/rules/no-invalid-void-type.md +++ b/packages/eslint-plugin/docs/rules/no-invalid-void-type.md @@ -1,6 +1,6 @@ -# `no-invalid-void-type` - -Disallows `void` type outside of generic or return types. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-invalid-void-type** for documentation. Disallows usage of `void` type outside of return types or generic type arguments. If `void` is used as return type, it shouldn’t be a part of intersection/union type with most other types. diff --git a/packages/eslint-plugin/docs/rules/no-loop-func.md b/packages/eslint-plugin/docs/rules/no-loop-func.md index 890bd80ecc06..906ab28e856a 100644 --- a/packages/eslint-plugin/docs/rules/no-loop-func.md +++ b/packages/eslint-plugin/docs/rules/no-loop-func.md @@ -1,6 +1,6 @@ -# `no-loop-func` - -Disallows function declarations that contain unsafe references inside loop statements. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-loop-func** for documentation. ## Rule Details diff --git a/packages/eslint-plugin/docs/rules/no-loss-of-precision.md b/packages/eslint-plugin/docs/rules/no-loss-of-precision.md index a27701afdfba..bf0ed85f39d3 100644 --- a/packages/eslint-plugin/docs/rules/no-loss-of-precision.md +++ b/packages/eslint-plugin/docs/rules/no-loss-of-precision.md @@ -1,6 +1,6 @@ -# `no-loss-of-precision` - -Disallows literal numbers that lose precision. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-loss-of-precision** for documentation. ## Rule Details diff --git a/packages/eslint-plugin/docs/rules/no-magic-numbers.md b/packages/eslint-plugin/docs/rules/no-magic-numbers.md index e5edc2e280d0..b352b892ffcf 100644 --- a/packages/eslint-plugin/docs/rules/no-magic-numbers.md +++ b/packages/eslint-plugin/docs/rules/no-magic-numbers.md @@ -1,6 +1,6 @@ -# `no-magic-numbers` - -Disallows magic numbers. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-magic-numbers** for documentation. ## Rule Details 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 fa348f30808d..e0aba22a7232 100644 --- a/packages/eslint-plugin/docs/rules/no-meaningless-void-operator.md +++ b/packages/eslint-plugin/docs/rules/no-meaningless-void-operator.md @@ -1,6 +1,6 @@ -# `no-meaningless-void-operator` - -Disallows the `void` operator except when used to discard a value. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-meaningless-void-operator** for documentation. Disallows the `void` operator when its argument is already of type `void` or `undefined`. diff --git a/packages/eslint-plugin/docs/rules/no-misused-new.md b/packages/eslint-plugin/docs/rules/no-misused-new.md index 10d0470f67bf..b79af1f3eb3b 100644 --- a/packages/eslint-plugin/docs/rules/no-misused-new.md +++ b/packages/eslint-plugin/docs/rules/no-misused-new.md @@ -1,6 +1,6 @@ -# `no-misused-new` - -Enforces valid definition of `new` and `constructor`. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-misused-new** for documentation. Warns on apparent attempts to define constructors for interfaces or `new` for classes. diff --git a/packages/eslint-plugin/docs/rules/no-misused-promises.md b/packages/eslint-plugin/docs/rules/no-misused-promises.md index f3e67234c6fe..62156bc8f134 100644 --- a/packages/eslint-plugin/docs/rules/no-misused-promises.md +++ b/packages/eslint-plugin/docs/rules/no-misused-promises.md @@ -1,6 +1,6 @@ -# `no-misused-promises` - -Disallows Promises in places not designed to handle them. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-misused-promises** for documentation. This rule forbids providing Promises to logical locations such as if statements in places where the TypeScript compiler allows them but they are not handled properly. These situations can often arise due to a missing `await` keyword or just a misunderstanding of the way async diff --git a/packages/eslint-plugin/docs/rules/no-namespace.md b/packages/eslint-plugin/docs/rules/no-namespace.md index e1e83fd1c7e5..f59c865c5b7d 100644 --- a/packages/eslint-plugin/docs/rules/no-namespace.md +++ b/packages/eslint-plugin/docs/rules/no-namespace.md @@ -1,6 +1,6 @@ -# `no-namespace` - -Disallows custom TypeScript modules and namespaces. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-namespace** for documentation. Custom TypeScript modules (`module foo {}`) and namespaces (`namespace foo {}`) are considered outdated ways to organize TypeScript code. ES2015 module syntax is now preferred (`import`/`export`). 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 29eac71f2f4e..b9008a8f78c7 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 @@ -1,6 +1,6 @@ -# `no-non-null-asserted-nullish-coalescing` - -Disallows non-null assertions in the left operand of a nullish coalescing operator. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-non-null-asserted-nullish-coalescing** for documentation. ## Rule Details 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 0913824ef8b7..aff4d5b47c41 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 @@ -1,6 +1,6 @@ -# `no-non-null-asserted-optional-chain` - -Disallows non-null assertions after an optional chain expression. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-non-null-asserted-optional-chain** for documentation. ## Rule Details 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 a28c07112a58..0eb9b4970c58 100644 --- a/packages/eslint-plugin/docs/rules/no-non-null-assertion.md +++ b/packages/eslint-plugin/docs/rules/no-non-null-assertion.md @@ -1,6 +1,6 @@ -# `no-non-null-assertion` - -Disallows non-null assertions using the `!` postfix operator. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-non-null-assertion** for documentation. ## Rule Details diff --git a/packages/eslint-plugin/docs/rules/no-parameter-properties.md b/packages/eslint-plugin/docs/rules/no-parameter-properties.md index 3ff367fb2e2b..3eaf06055033 100644 --- a/packages/eslint-plugin/docs/rules/no-parameter-properties.md +++ b/packages/eslint-plugin/docs/rules/no-parameter-properties.md @@ -1,6 +1,6 @@ -# `no-parameter-properties` - -Disallows the use of parameter properties in class constructors. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-parameter-properties** for documentation. Parameter properties can be confusing to those new to TypeScript as they are less explicit than other ways of declaring and initializing class members. diff --git a/packages/eslint-plugin/docs/rules/no-redeclare.md b/packages/eslint-plugin/docs/rules/no-redeclare.md index 6ddb0d6d7302..4ebaba2ee5ee 100644 --- a/packages/eslint-plugin/docs/rules/no-redeclare.md +++ b/packages/eslint-plugin/docs/rules/no-redeclare.md @@ -1,6 +1,6 @@ -# `no-redeclare` - -Disallows variable redeclaration. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-redeclare** for documentation. ## Rule Details 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 fc393d5c0d44..cbfde25358fd 100644 --- a/packages/eslint-plugin/docs/rules/no-redundant-type-constituents.md +++ b/packages/eslint-plugin/docs/rules/no-redundant-type-constituents.md @@ -1,6 +1,6 @@ -# `no-redundant-type-constituents` - -Disallows members of unions and intersections that do nothing or override type information. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-redundant-type-constituents** for documentation. ## Rule Details diff --git a/packages/eslint-plugin/docs/rules/no-require-imports.md b/packages/eslint-plugin/docs/rules/no-require-imports.md index 9e45c8bd4339..0a3ddd5d2f9f 100644 --- a/packages/eslint-plugin/docs/rules/no-require-imports.md +++ b/packages/eslint-plugin/docs/rules/no-require-imports.md @@ -1,6 +1,6 @@ -# `no-require-imports` - -Disallows invocation of `require()`. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-require-imports** for documentation. Prefer the newer ES6-style imports over `require()`. diff --git a/packages/eslint-plugin/docs/rules/no-restricted-imports.md b/packages/eslint-plugin/docs/rules/no-restricted-imports.md index 2e741490d098..89f615c194e2 100644 --- a/packages/eslint-plugin/docs/rules/no-restricted-imports.md +++ b/packages/eslint-plugin/docs/rules/no-restricted-imports.md @@ -1,6 +1,6 @@ -# `no-restricted-imports` - -Disallows specified modules when loaded by `import`. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-restricted-imports** for documentation. ## Rule Details diff --git a/packages/eslint-plugin/docs/rules/no-shadow.md b/packages/eslint-plugin/docs/rules/no-shadow.md index 4ed7f199c2ca..3da0a6bc6fbd 100644 --- a/packages/eslint-plugin/docs/rules/no-shadow.md +++ b/packages/eslint-plugin/docs/rules/no-shadow.md @@ -1,6 +1,6 @@ -# `no-shadow` - -Disallows variable declarations from shadowing variables declared in the outer scope. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-shadow** for documentation. ## Rule Details diff --git a/packages/eslint-plugin/docs/rules/no-this-alias.md b/packages/eslint-plugin/docs/rules/no-this-alias.md index 8485ef88c071..3433ae28eb0c 100644 --- a/packages/eslint-plugin/docs/rules/no-this-alias.md +++ b/packages/eslint-plugin/docs/rules/no-this-alias.md @@ -1,6 +1,6 @@ -# `no-this-alias` - -Disallows aliasing `this`. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-this-alias** for documentation. This rule prohibits assigning variables to `this`. diff --git a/packages/eslint-plugin/docs/rules/no-throw-literal.md b/packages/eslint-plugin/docs/rules/no-throw-literal.md index 4bb8bbcc58c9..a95aeb1a06b5 100644 --- a/packages/eslint-plugin/docs/rules/no-throw-literal.md +++ b/packages/eslint-plugin/docs/rules/no-throw-literal.md @@ -1,6 +1,6 @@ -# `no-throw-literal` - -Disallows throwing literals as exceptions. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-throw-literal** for documentation. It is considered good practice to only `throw` the `Error` object itself or an object using the `Error` object as base objects for user-defined exceptions. The fundamental benefit of `Error` objects is that they automatically keep track of where they were built and originated. diff --git a/packages/eslint-plugin/docs/rules/no-type-alias.md b/packages/eslint-plugin/docs/rules/no-type-alias.md index 3a02c4b9760d..e2b95b917382 100644 --- a/packages/eslint-plugin/docs/rules/no-type-alias.md +++ b/packages/eslint-plugin/docs/rules/no-type-alias.md @@ -1,6 +1,6 @@ -# `no-type-alias` - -Disallows type aliases. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-type-alias** for documentation. In TypeScript, type aliases serve three purposes: 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 73f5ac0c06a8..80142fe65380 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 @@ -1,6 +1,6 @@ -# `no-unnecessary-boolean-literal-compare` - -Disallows unnecessary equality comparisons against boolean literals. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-unnecessary-boolean-literal-compare** for documentation. Comparing boolean values to boolean literals is unnecessary, those comparisons result in the same booleans. Using the boolean values directly, or via a unary negation (`!value`), is more concise and clearer. diff --git a/packages/eslint-plugin/docs/rules/no-unnecessary-condition.md b/packages/eslint-plugin/docs/rules/no-unnecessary-condition.md index 3c03a5655217..2594184ea02b 100644 --- a/packages/eslint-plugin/docs/rules/no-unnecessary-condition.md +++ b/packages/eslint-plugin/docs/rules/no-unnecessary-condition.md @@ -1,6 +1,6 @@ -# `no-unnecessary-condition` - -Disallows conditionals where the type is always truthy or always falsy. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-unnecessary-condition** for documentation. Any expression being used as a condition must be able to evaluate as truthy or falsy in order to be considered "necessary". Conversely, any expression that always evaluates to truthy or always evaluates to falsy, as determined by the type of the expression, is considered unnecessary and will be flagged by this rule. diff --git a/packages/eslint-plugin/docs/rules/no-unnecessary-qualifier.md b/packages/eslint-plugin/docs/rules/no-unnecessary-qualifier.md index db73814ee788..31905c485f4d 100644 --- a/packages/eslint-plugin/docs/rules/no-unnecessary-qualifier.md +++ b/packages/eslint-plugin/docs/rules/no-unnecessary-qualifier.md @@ -1,6 +1,6 @@ -# `no-unnecessary-qualifier` - -Disallows unnecessary namespace qualifiers. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-unnecessary-qualifier** for documentation. ## Rule Details 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 26e5c5a01cbb..6f15d1493753 100644 --- a/packages/eslint-plugin/docs/rules/no-unnecessary-type-arguments.md +++ b/packages/eslint-plugin/docs/rules/no-unnecessary-type-arguments.md @@ -1,6 +1,6 @@ -# `no-unnecessary-type-arguments` - -Disallows type arguments that are equal to the default. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-unnecessary-type-arguments** for documentation. Warns if an explicitly specified type argument is the default for that type parameter. diff --git a/packages/eslint-plugin/docs/rules/no-unnecessary-type-assertion.md b/packages/eslint-plugin/docs/rules/no-unnecessary-type-assertion.md index e801c73f0ca5..b8e91cf74c49 100644 --- a/packages/eslint-plugin/docs/rules/no-unnecessary-type-assertion.md +++ b/packages/eslint-plugin/docs/rules/no-unnecessary-type-assertion.md @@ -1,6 +1,6 @@ -# `no-unnecessary-type-assertion` - -Disallows type assertions that do not change the type of an expression. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-unnecessary-type-assertion** for documentation. This rule prohibits using a type assertion that does not change the type of an expression. diff --git a/packages/eslint-plugin/docs/rules/no-unnecessary-type-constraint.md b/packages/eslint-plugin/docs/rules/no-unnecessary-type-constraint.md index b2fb9c6b2b95..4cd813ec0d6d 100644 --- a/packages/eslint-plugin/docs/rules/no-unnecessary-type-constraint.md +++ b/packages/eslint-plugin/docs/rules/no-unnecessary-type-constraint.md @@ -1,6 +1,6 @@ -# `no-unnecessary-type-constraint` - -Disallows unnecessary constraints on generic types. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-unnecessary-type-constraint** for documentation. ## Rule Details diff --git a/packages/eslint-plugin/docs/rules/no-unsafe-argument.md b/packages/eslint-plugin/docs/rules/no-unsafe-argument.md index 30d7e441e661..15e1c82e7ff6 100644 --- a/packages/eslint-plugin/docs/rules/no-unsafe-argument.md +++ b/packages/eslint-plugin/docs/rules/no-unsafe-argument.md @@ -1,6 +1,6 @@ -# `no-unsafe-argument` - -Disallows calling a function with a value with type `any`. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-unsafe-argument** for documentation. Despite your best intentions, the `any` type can sometimes leak into your codebase. Call a function with `any` typed argument are not checked at all by TypeScript, so it creates a potential safety hole, and source of bugs in your codebase. diff --git a/packages/eslint-plugin/docs/rules/no-unsafe-assignment.md b/packages/eslint-plugin/docs/rules/no-unsafe-assignment.md index 98bb047e7863..309d0b13d2e8 100644 --- a/packages/eslint-plugin/docs/rules/no-unsafe-assignment.md +++ b/packages/eslint-plugin/docs/rules/no-unsafe-assignment.md @@ -1,6 +1,6 @@ -# `no-unsafe-assignment` - -Disallows assigning a value with type `any` to variables and properties. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-unsafe-assignment** for documentation. Despite your best intentions, the `any` type can sometimes leak into your codebase. Assigning an `any` typed value to a variable can be hard to pick up on, particularly if it leaks in from an external library. Operations on the variable will not be checked at all by TypeScript, so it creates a potential safety hole, and source of bugs in your codebase. diff --git a/packages/eslint-plugin/docs/rules/no-unsafe-call.md b/packages/eslint-plugin/docs/rules/no-unsafe-call.md index 68c5ba8b81c5..103aa55e7b23 100644 --- a/packages/eslint-plugin/docs/rules/no-unsafe-call.md +++ b/packages/eslint-plugin/docs/rules/no-unsafe-call.md @@ -1,6 +1,6 @@ -# `no-unsafe-call` - -Disallows calling a value with type `any`. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-unsafe-call** for documentation. Despite your best intentions, the `any` type can sometimes leak into your codebase. The arguments to, and return value of calling an `any` typed variable are not checked at all by TypeScript, so it creates a potential safety hole, and source of bugs in your codebase. 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 a79a8c648c5c..c90028aa6643 100644 --- a/packages/eslint-plugin/docs/rules/no-unsafe-member-access.md +++ b/packages/eslint-plugin/docs/rules/no-unsafe-member-access.md @@ -1,6 +1,6 @@ -# `no-unsafe-member-access` - -Disallows member access on a value with type `any`. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-unsafe-member-access** for documentation. Despite your best intentions, the `any` type can sometimes leak into your codebase. Member access on `any` typed variables is not checked at all by TypeScript, so it creates a potential safety hole, and source of bugs in your codebase. diff --git a/packages/eslint-plugin/docs/rules/no-unsafe-return.md b/packages/eslint-plugin/docs/rules/no-unsafe-return.md index a3401b3b94ee..d2e5a36f309c 100644 --- a/packages/eslint-plugin/docs/rules/no-unsafe-return.md +++ b/packages/eslint-plugin/docs/rules/no-unsafe-return.md @@ -1,6 +1,6 @@ -# `no-unsafe-return` - -Disallows returning a value with type `any` from a function. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-unsafe-return** for documentation. Despite your best intentions, the `any` type can sometimes leak into your codebase. Returned `any` typed values are not checked at all by TypeScript, so it creates a potential safety hole, and source of bugs in your codebase. diff --git a/packages/eslint-plugin/docs/rules/no-unused-expressions.md b/packages/eslint-plugin/docs/rules/no-unused-expressions.md index f89aa6349e7d..2e6a002ba51c 100644 --- a/packages/eslint-plugin/docs/rules/no-unused-expressions.md +++ b/packages/eslint-plugin/docs/rules/no-unused-expressions.md @@ -1,6 +1,6 @@ -# `no-unused-expressions` - -Disallows unused expressions. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-unused-expressions** for documentation. ## Rule Details diff --git a/packages/eslint-plugin/docs/rules/no-unused-vars.md b/packages/eslint-plugin/docs/rules/no-unused-vars.md index 7b46ad3f59cf..4902c1e72592 100644 --- a/packages/eslint-plugin/docs/rules/no-unused-vars.md +++ b/packages/eslint-plugin/docs/rules/no-unused-vars.md @@ -1,6 +1,6 @@ -# `no-unused-vars` - -Disallows unused variables. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-unused-vars** for documentation. ## Rule Details diff --git a/packages/eslint-plugin/docs/rules/no-use-before-define.md b/packages/eslint-plugin/docs/rules/no-use-before-define.md index ec29f33c821d..dfc9c354d49d 100644 --- a/packages/eslint-plugin/docs/rules/no-use-before-define.md +++ b/packages/eslint-plugin/docs/rules/no-use-before-define.md @@ -1,6 +1,6 @@ -# `no-use-before-define` - -Disallows the use of variables before they are defined. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-use-before-define** for documentation. ## Rule Details diff --git a/packages/eslint-plugin/docs/rules/no-useless-constructor.md b/packages/eslint-plugin/docs/rules/no-useless-constructor.md index 221a0aaad202..8892c1c9e29e 100644 --- a/packages/eslint-plugin/docs/rules/no-useless-constructor.md +++ b/packages/eslint-plugin/docs/rules/no-useless-constructor.md @@ -1,6 +1,6 @@ -# `no-useless-constructor` - -Disallows unnecessary constructors. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-useless-constructor** for documentation. ## Rule Details 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 94d8dc8a08c8..1687bfacc91b 100644 --- a/packages/eslint-plugin/docs/rules/no-useless-empty-export.md +++ b/packages/eslint-plugin/docs/rules/no-useless-empty-export.md @@ -1,6 +1,6 @@ -# `no-useless-empty-export` - -Disallows empty exports that don't change anything in a module file. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-useless-empty-export** for documentation. ## Rule Details diff --git a/packages/eslint-plugin/docs/rules/no-var-requires.md b/packages/eslint-plugin/docs/rules/no-var-requires.md index 1ec377b2ba13..247535b011e9 100644 --- a/packages/eslint-plugin/docs/rules/no-var-requires.md +++ b/packages/eslint-plugin/docs/rules/no-var-requires.md @@ -1,6 +1,6 @@ -# `no-var-requires` - -Disallows `require` statements except in import statements. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/no-var-requires** for documentation. In other words, the use of forms such as `var foo = require("foo")` are banned. Instead use ES6 style imports or `import foo = require("foo")` imports. 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 ffb0d7b4e704..486f464d77e1 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 @@ -1,6 +1,6 @@ -# `non-nullable-type-assertion-style` - -Enforces non-null assertions over explicit type casts. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/non-nullable-type-assertion-style** for documentation. This rule detects when an `as` cast is doing the same job as a `!` would, and suggests fixing the code to be an `!`. diff --git a/packages/eslint-plugin/docs/rules/object-curly-spacing.md b/packages/eslint-plugin/docs/rules/object-curly-spacing.md index 4789df3e14e4..31f878363b19 100644 --- a/packages/eslint-plugin/docs/rules/object-curly-spacing.md +++ b/packages/eslint-plugin/docs/rules/object-curly-spacing.md @@ -1,6 +1,6 @@ -# `object-curly-spacing` - -Enforces consistent spacing inside braces. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/object-curly-spacing** for documentation. ## Rule Details diff --git a/packages/eslint-plugin/docs/rules/padding-line-between-statements.md b/packages/eslint-plugin/docs/rules/padding-line-between-statements.md index 82f98043d4b7..69951c378524 100644 --- a/packages/eslint-plugin/docs/rules/padding-line-between-statements.md +++ b/packages/eslint-plugin/docs/rules/padding-line-between-statements.md @@ -1,6 +1,6 @@ -# `padding-line-between-statements` - -Requires or disallows padding lines between statements. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/padding-line-between-statements** for documentation. ## Rule Details diff --git a/packages/eslint-plugin/docs/rules/parameter-properties.md b/packages/eslint-plugin/docs/rules/parameter-properties.md index e4ff9a4ea8a1..3b8e4821ea3b 100644 --- a/packages/eslint-plugin/docs/rules/parameter-properties.md +++ b/packages/eslint-plugin/docs/rules/parameter-properties.md @@ -1,6 +1,6 @@ -# `parameter-properties` - -Requires or disallows parameter properties in class constructors. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/parameter-properties** for documentation. Parameter properties can be confusing to those new to TypeScript as they are less explicit than other ways of declaring and initializing class members. diff --git a/packages/eslint-plugin/docs/rules/prefer-as-const.md b/packages/eslint-plugin/docs/rules/prefer-as-const.md index 76d3dede5472..ce6de3345444 100644 --- a/packages/eslint-plugin/docs/rules/prefer-as-const.md +++ b/packages/eslint-plugin/docs/rules/prefer-as-const.md @@ -1,6 +1,6 @@ -# `prefer-as-const` - -Enforces the use of `as const` over literal type. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/prefer-as-const** for documentation. This rule recommends usage of `const` assertion when type primitive value is equal to type. diff --git a/packages/eslint-plugin/docs/rules/prefer-enum-initializers.md b/packages/eslint-plugin/docs/rules/prefer-enum-initializers.md index fb3a24494d46..c16f00bc8641 100644 --- a/packages/eslint-plugin/docs/rules/prefer-enum-initializers.md +++ b/packages/eslint-plugin/docs/rules/prefer-enum-initializers.md @@ -1,6 +1,6 @@ -# `prefer-enum-initializers` - -Requires each enum member value to be explicitly initialized. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/prefer-enum-initializers** for documentation. This rule recommends having each `enum`s member value explicitly initialized. diff --git a/packages/eslint-plugin/docs/rules/prefer-for-of.md b/packages/eslint-plugin/docs/rules/prefer-for-of.md index f4a4f207e78d..575e45b39e15 100644 --- a/packages/eslint-plugin/docs/rules/prefer-for-of.md +++ b/packages/eslint-plugin/docs/rules/prefer-for-of.md @@ -1,6 +1,6 @@ -# `prefer-for-of` - -Enforces the use of `for-of` loop over the standard `for` loop where possible. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/prefer-for-of** for documentation. This rule recommends a for-of loop when the loop index is only used to read from an array that is being iterated. diff --git a/packages/eslint-plugin/docs/rules/prefer-function-type.md b/packages/eslint-plugin/docs/rules/prefer-function-type.md index 22b579798fc5..8c0e9de2b5ca 100644 --- a/packages/eslint-plugin/docs/rules/prefer-function-type.md +++ b/packages/eslint-plugin/docs/rules/prefer-function-type.md @@ -1,6 +1,6 @@ -# `prefer-function-type` - -Enforces using function types instead of interfaces with call signatures. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/prefer-function-type** for documentation. ## Rule Details diff --git a/packages/eslint-plugin/docs/rules/prefer-includes.md b/packages/eslint-plugin/docs/rules/prefer-includes.md index 448d6bef4a31..3eec29ab8923 100644 --- a/packages/eslint-plugin/docs/rules/prefer-includes.md +++ b/packages/eslint-plugin/docs/rules/prefer-includes.md @@ -1,6 +1,6 @@ -# `prefer-includes` - -Enforces `includes` method over `indexOf` method. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/prefer-includes** for documentation. Until ES5, we were using `String#indexOf` method to check whether a string contains an arbitrary substring or not. Until ES2015, we were using `Array#indexOf` method to check whether an array contains an arbitrary value or not. 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 4f4db49cb625..31f452be2ef4 100644 --- a/packages/eslint-plugin/docs/rules/prefer-literal-enum-member.md +++ b/packages/eslint-plugin/docs/rules/prefer-literal-enum-member.md @@ -1,6 +1,6 @@ -# `prefer-literal-enum-member` - -Requires all enum members to be literal values. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/prefer-literal-enum-member** for documentation. TypeScript allows the value of an enum member to be many different kinds of valid JavaScript expressions. However, because enums create their own scope whereby each enum member becomes a variable in that scope, unexpected values could be used at runtime. Example: diff --git a/packages/eslint-plugin/docs/rules/prefer-namespace-keyword.md b/packages/eslint-plugin/docs/rules/prefer-namespace-keyword.md index 01bd2377a0fa..bc7b601934d2 100644 --- a/packages/eslint-plugin/docs/rules/prefer-namespace-keyword.md +++ b/packages/eslint-plugin/docs/rules/prefer-namespace-keyword.md @@ -1,6 +1,6 @@ -# `prefer-namespace-keyword` - -Requires using `namespace` keyword over `module` keyword to declare custom TypeScript modules. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/prefer-namespace-keyword** for documentation. In an effort to prevent further confusion between custom TypeScript modules and the new ES2015 modules, starting with TypeScript `v1.5` the keyword `namespace` is now the preferred way to declare custom TypeScript modules. diff --git a/packages/eslint-plugin/docs/rules/prefer-nullish-coalescing.md b/packages/eslint-plugin/docs/rules/prefer-nullish-coalescing.md index 9b1dfe988209..c82399072ddc 100644 --- a/packages/eslint-plugin/docs/rules/prefer-nullish-coalescing.md +++ b/packages/eslint-plugin/docs/rules/prefer-nullish-coalescing.md @@ -1,6 +1,6 @@ -# `prefer-nullish-coalescing` - -Enforces using the nullish coalescing operator instead of logical chaining. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/prefer-nullish-coalescing** for documentation. TypeScript 3.7 added support for the nullish coalescing operator. This operator allows you to safely cascade a value when dealing with `null` or `undefined`. @@ -46,6 +46,7 @@ This rule aims enforce the usage of the safer operator. ```ts type Options = [ { + ignoreTernaryTests?: boolean; ignoreConditionalTests?: boolean; ignoreMixedLogicalExpressions?: boolean; }, @@ -53,12 +54,53 @@ type Options = [ const defaultOptions = [ { + ignoreTernaryTests: true; ignoreConditionalTests: true, ignoreMixedLogicalExpressions: true, }, ]; ``` +### `ignoreTernaryTests` + +Setting this option to `true` (the default) will cause the rule to ignore any ternary expressions that could be simplified by using the nullish coalescing operator. + +Incorrect code for `ignoreTernaryTests: false`, and correct code for `ignoreTernaryTests: true`: + +```ts +const foo: any = 'bar'; +foo !== undefined && foo !== null ? foo : 'a string'; +foo === undefined || foo === null ? 'a string' : foo; +foo == undefined ? 'a string' : foo; +foo == null ? 'a string' : foo; + +const foo: string | undefined = 'bar'; +foo !== undefined ? foo : 'a string'; +foo === undefined ? 'a string' : foo; + +const foo: string | null = 'bar'; +foo !== null ? foo : 'a string'; +foo === null ? 'a string' : foo; +``` + +Correct code for `ignoreTernaryTests: false`: + +```ts +const foo: any = 'bar'; +foo ?? 'a string'; +foo ?? 'a string'; +foo ?? 'a string'; +foo ?? 'a string'; + +const foo: string | undefined = 'bar'; +foo ?? 'a string'; +foo ?? 'a string'; + +const foo: string | null = 'bar'; +foo ?? 'a string'; +foo ?? 'a string'; +``` + ### `ignoreConditionalTests` Setting this option to `true` (the default) will cause the rule to ignore any cases that are located within a conditional test. diff --git a/packages/eslint-plugin/docs/rules/prefer-optional-chain.md b/packages/eslint-plugin/docs/rules/prefer-optional-chain.md index c2b196a04a47..730842c1512d 100644 --- a/packages/eslint-plugin/docs/rules/prefer-optional-chain.md +++ b/packages/eslint-plugin/docs/rules/prefer-optional-chain.md @@ -1,6 +1,6 @@ -# `prefer-optional-chain` - -Enforces using concise optional chain expressions instead of chained logical ands. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/prefer-optional-chain** for documentation. TypeScript 3.7 added support for the optional chain operator. This operator allows you to safely access properties and methods on objects when they are potentially `null` or `undefined`. 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 5ac98d6f043f..022b4e841bc9 100644 --- a/packages/eslint-plugin/docs/rules/prefer-readonly-parameter-types.md +++ b/packages/eslint-plugin/docs/rules/prefer-readonly-parameter-types.md @@ -1,6 +1,6 @@ -# `prefer-readonly-parameter-types` - -Requires function parameters to be typed as `readonly` to prevent accidental mutation of inputs. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/prefer-readonly-parameter-types** for documentation. Mutating function arguments can lead to confusing, hard to debug behavior. Whilst it's easy to implicitly remember to not modify function arguments, explicitly typing arguments as readonly provides clear contract to consumers. diff --git a/packages/eslint-plugin/docs/rules/prefer-readonly.md b/packages/eslint-plugin/docs/rules/prefer-readonly.md index bfc297ae8fc3..e21f26a278ba 100644 --- a/packages/eslint-plugin/docs/rules/prefer-readonly.md +++ b/packages/eslint-plugin/docs/rules/prefer-readonly.md @@ -1,6 +1,6 @@ -# `prefer-readonly` - -Requires private members to be marked as `readonly` if they're never modified outside of the constructor. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/prefer-readonly** for documentation. This rule enforces that private members are marked as `readonly` if they're never modified outside of the constructor. 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 16a1046a24da..5db156aa47f2 100644 --- a/packages/eslint-plugin/docs/rules/prefer-reduce-type-parameter.md +++ b/packages/eslint-plugin/docs/rules/prefer-reduce-type-parameter.md @@ -1,6 +1,6 @@ -# `prefer-reduce-type-parameter` - -Enforces using type parameter when calling `Array#reduce` instead of casting. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/prefer-reduce-type-parameter** for documentation. It's common to call `Array#reduce` with a generic type, such as an array or object, as the initial value. Since these values are empty, their types are not usable: diff --git a/packages/eslint-plugin/docs/rules/prefer-regexp-exec.md b/packages/eslint-plugin/docs/rules/prefer-regexp-exec.md index 7c7756646b91..a487ea3d3e24 100644 --- a/packages/eslint-plugin/docs/rules/prefer-regexp-exec.md +++ b/packages/eslint-plugin/docs/rules/prefer-regexp-exec.md @@ -1,6 +1,6 @@ -# `prefer-regexp-exec` - -Enforces `RegExp#exec` over `String#match` if no global flag is provided. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/prefer-regexp-exec** for documentation. As `String#match` is defined to be the same as `RegExp#exec` when the regular expression does not include the `g` flag, prefer a consistent usage. diff --git a/packages/eslint-plugin/docs/rules/prefer-return-this-type.md b/packages/eslint-plugin/docs/rules/prefer-return-this-type.md index 2ec748340126..0581d81ad02b 100644 --- a/packages/eslint-plugin/docs/rules/prefer-return-this-type.md +++ b/packages/eslint-plugin/docs/rules/prefer-return-this-type.md @@ -1,6 +1,6 @@ -# `prefer-return-this-type` - -Enforces that `this` is used when only `this` type is returned. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/prefer-return-this-type** for documentation. [Method chaining](https://en.wikipedia.org/wiki/Method_chaining) is a common pattern in OOP languages and TypeScript provides a special [polymorphic this type](https://www.typescriptlang.org/docs/handbook/2/classes.html#this-types). If any type other than `this` is specified as the return type of these chaining methods, TypeScript will fail to cast it when invoking in subclass. 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 c103769e1ef1..2be24df3c21b 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 @@ -1,9 +1,8 @@ -# `prefer-string-starts-ends-with` - -Enforces using `String#startsWith` and `String#endsWith` over other equivalent methods of checking substrings. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/prefer-string-starts-ends-with** for documentation. There are multiple ways to verify if a string starts or ends with a specific string, such as `foo.indexOf('bar') === 0`. - Since ES2015 has added `String#startsWith` and `String#endsWith`, this rule reports other ways to be consistent. ## Rule Details 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 bf96eb8fa9a6..bfcaad11b0ab 100644 --- a/packages/eslint-plugin/docs/rules/prefer-ts-expect-error.md +++ b/packages/eslint-plugin/docs/rules/prefer-ts-expect-error.md @@ -1,6 +1,6 @@ -# `prefer-ts-expect-error` - -Enforces using `@ts-expect-error` over `@ts-ignore`. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/prefer-ts-expect-error** for documentation. TypeScript allows you to suppress all errors on a line by placing a single-line comment or a comment block line starting with `@ts-ignore` immediately before the erroring line. While powerful, there is no way to know if a `@ts-ignore` is actually suppressing an error without manually investigating what happens when the `@ts-ignore` is removed. diff --git a/packages/eslint-plugin/docs/rules/promise-function-async.md b/packages/eslint-plugin/docs/rules/promise-function-async.md index 7316e02f1b32..424536ee5f24 100644 --- a/packages/eslint-plugin/docs/rules/promise-function-async.md +++ b/packages/eslint-plugin/docs/rules/promise-function-async.md @@ -1,6 +1,6 @@ -# `promise-function-async` - -Requires any function or method that returns a Promise to be marked async. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/promise-function-async** for documentation. Ensures that each function is only capable of: diff --git a/packages/eslint-plugin/docs/rules/quotes.md b/packages/eslint-plugin/docs/rules/quotes.md index 1e3f6d32363d..61cadea2047a 100644 --- a/packages/eslint-plugin/docs/rules/quotes.md +++ b/packages/eslint-plugin/docs/rules/quotes.md @@ -1,6 +1,6 @@ -# `quotes` - -Enforces the consistent use of either backticks, double, or single quotes. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/quotes** for documentation. ## Rule Details 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 23694f06d6ae..d4b006c1d70f 100644 --- a/packages/eslint-plugin/docs/rules/require-array-sort-compare.md +++ b/packages/eslint-plugin/docs/rules/require-array-sort-compare.md @@ -1,9 +1,8 @@ -# `require-array-sort-compare` - -Requires `Array#sort` calls to always provide a `compareFunction`. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/require-array-sort-compare** for documentation. This rule prevents invoking the `Array#sort()` method without providing a `compare` argument. - When called without a compare function, `Array#sort()` converts all non-undefined array elements into strings and then compares said strings based off their UTF-16 code units. The result is that elements are sorted alphabetically, regardless of their type. diff --git a/packages/eslint-plugin/docs/rules/require-await.md b/packages/eslint-plugin/docs/rules/require-await.md index f4ac8cf56766..21d6271c38c4 100644 --- a/packages/eslint-plugin/docs/rules/require-await.md +++ b/packages/eslint-plugin/docs/rules/require-await.md @@ -1,6 +1,6 @@ -# `require-await` - -Disallows async functions which have no `await` expression. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/require-await** for documentation. ## Rule Details diff --git a/packages/eslint-plugin/docs/rules/restrict-plus-operands.md b/packages/eslint-plugin/docs/rules/restrict-plus-operands.md index a8b4a83f288f..5b984f0b21c5 100644 --- a/packages/eslint-plugin/docs/rules/restrict-plus-operands.md +++ b/packages/eslint-plugin/docs/rules/restrict-plus-operands.md @@ -1,6 +1,6 @@ -# `restrict-plus-operands` - -Requires both operands of addition to have type `number` or `string`. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/restrict-plus-operands** for documentation. ## Rule Details diff --git a/packages/eslint-plugin/docs/rules/restrict-template-expressions.md b/packages/eslint-plugin/docs/rules/restrict-template-expressions.md index 59c507f167e2..37423d23abc4 100644 --- a/packages/eslint-plugin/docs/rules/restrict-template-expressions.md +++ b/packages/eslint-plugin/docs/rules/restrict-template-expressions.md @@ -1,6 +1,6 @@ -# `restrict-template-expressions` - -Enforces template literal expressions to be of `string` type. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/restrict-template-expressions** for documentation. ## Rule Details diff --git a/packages/eslint-plugin/docs/rules/return-await.md b/packages/eslint-plugin/docs/rules/return-await.md index 20e99158dffa..1aa62401ae49 100644 --- a/packages/eslint-plugin/docs/rules/return-await.md +++ b/packages/eslint-plugin/docs/rules/return-await.md @@ -1,6 +1,6 @@ -# `return-await` - -Enforces consistent returning of awaited values. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/return-await** for documentation. Returning an awaited promise can make sense for better stack trace information as well as for consistent error handling (returned promises will not be caught in an async function try/catch). diff --git a/packages/eslint-plugin/docs/rules/semi.md b/packages/eslint-plugin/docs/rules/semi.md index 307637c7168e..0c37c9f4baa8 100644 --- a/packages/eslint-plugin/docs/rules/semi.md +++ b/packages/eslint-plugin/docs/rules/semi.md @@ -1,6 +1,6 @@ -# `semi` - -Requires or disallows semicolons instead of ASI. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/semi** for documentation. This rule enforces consistent use of semicolons after statements. diff --git a/packages/eslint-plugin/docs/rules/sort-type-union-intersection-members.md b/packages/eslint-plugin/docs/rules/sort-type-union-intersection-members.md index a7444659ee34..0e02b686b87e 100644 --- a/packages/eslint-plugin/docs/rules/sort-type-union-intersection-members.md +++ b/packages/eslint-plugin/docs/rules/sort-type-union-intersection-members.md @@ -1,6 +1,6 @@ -# `sort-type-union-intersection-members` - -Enforces members of a type union/intersection to be sorted alphabetically. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/sort-type-union-intersection-members** for documentation. Sorting union (`|`) and intersection (`&`) types can help: diff --git a/packages/eslint-plugin/docs/rules/space-before-blocks.md b/packages/eslint-plugin/docs/rules/space-before-blocks.md index 5ff10537795f..bb2ec8e4b890 100644 --- a/packages/eslint-plugin/docs/rules/space-before-blocks.md +++ b/packages/eslint-plugin/docs/rules/space-before-blocks.md @@ -1,6 +1,6 @@ -# `space-before-blocks` - -Enforces consistent spacing before blocks. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/space-before-blocks** for documentation. ## Rule Details diff --git a/packages/eslint-plugin/docs/rules/space-before-function-paren.md b/packages/eslint-plugin/docs/rules/space-before-function-paren.md index 4664dd4c6a51..80ab4ffc6a0d 100644 --- a/packages/eslint-plugin/docs/rules/space-before-function-paren.md +++ b/packages/eslint-plugin/docs/rules/space-before-function-paren.md @@ -1,6 +1,6 @@ -# `space-before-function-paren` - -Enforces consistent spacing before function parenthesis. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/space-before-function-paren** for documentation. ## Rule Details diff --git a/packages/eslint-plugin/docs/rules/space-infix-ops.md b/packages/eslint-plugin/docs/rules/space-infix-ops.md index afcb5de8e788..e791420b6530 100644 --- a/packages/eslint-plugin/docs/rules/space-infix-ops.md +++ b/packages/eslint-plugin/docs/rules/space-infix-ops.md @@ -1,6 +1,6 @@ -# `space-infix-ops` - -Requires spacing around infix operators. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/space-infix-ops** for documentation. This rule extends the base [`eslint/space-infix-ops`](https://eslint.org/docs/rules/space-infix-ops) rule. diff --git a/packages/eslint-plugin/docs/rules/strict-boolean-expressions.md b/packages/eslint-plugin/docs/rules/strict-boolean-expressions.md index 16ceb26aa8fe..a86e8146ba6f 100644 --- a/packages/eslint-plugin/docs/rules/strict-boolean-expressions.md +++ b/packages/eslint-plugin/docs/rules/strict-boolean-expressions.md @@ -1,6 +1,6 @@ -# `strict-boolean-expressions` - -Disallows certain types in boolean expressions. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/strict-boolean-expressions** for documentation. Forbids usage of non-boolean types in expressions where a boolean is expected. `boolean` and `never` types are always allowed. diff --git a/packages/eslint-plugin/docs/rules/switch-exhaustiveness-check.md b/packages/eslint-plugin/docs/rules/switch-exhaustiveness-check.md index 7e6126830d4c..cfe2ef234a46 100644 --- a/packages/eslint-plugin/docs/rules/switch-exhaustiveness-check.md +++ b/packages/eslint-plugin/docs/rules/switch-exhaustiveness-check.md @@ -1,6 +1,6 @@ -# `switch-exhaustiveness-check` - -Requires switch-case statements to be exhaustive with union type. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/switch-exhaustiveness-check** for documentation. Union type may have a lot of parts. It's easy to forget to consider all cases in switch. This rule reminds which parts are missing. If domain of the problem requires to have only a partial switch, developer may _explicitly_ add a default clause. diff --git a/packages/eslint-plugin/docs/rules/triple-slash-reference.md b/packages/eslint-plugin/docs/rules/triple-slash-reference.md index 97f4fb77dab4..ce73a33d5942 100644 --- a/packages/eslint-plugin/docs/rules/triple-slash-reference.md +++ b/packages/eslint-plugin/docs/rules/triple-slash-reference.md @@ -1,6 +1,6 @@ -# `triple-slash-reference` - -Disallows certain triple slash directives in favor of ES6-style import declarations. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/triple-slash-reference** for documentation. Use of triple-slash reference type directives is discouraged in favor of the newer `import` style. This rule allows you to ban use of `/// `, `/// `, or `/// ` directives. diff --git a/packages/eslint-plugin/docs/rules/type-annotation-spacing.md b/packages/eslint-plugin/docs/rules/type-annotation-spacing.md index 475ad29ca4d1..7adc9fd0e59e 100644 --- a/packages/eslint-plugin/docs/rules/type-annotation-spacing.md +++ b/packages/eslint-plugin/docs/rules/type-annotation-spacing.md @@ -1,6 +1,6 @@ -# `type-annotation-spacing` - -Requires consistent spacing around type annotations. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/type-annotation-spacing** for documentation. Spacing around type annotations improves readability of the code. Although the most commonly used style guideline for type annotations in TypeScript prescribes adding a space after the colon, but not before it, it is subjective to the preferences of a project. For example: diff --git a/packages/eslint-plugin/docs/rules/typedef.md b/packages/eslint-plugin/docs/rules/typedef.md index 5356cdd7a2d7..8976c5211974 100644 --- a/packages/eslint-plugin/docs/rules/typedef.md +++ b/packages/eslint-plugin/docs/rules/typedef.md @@ -1,6 +1,6 @@ -# `typedef` - -Requires type annotations in certain places. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/typedef** for documentation. TypeScript cannot always infer types for all places in code. Some locations require type annotations for their types to be inferred. diff --git a/packages/eslint-plugin/docs/rules/unbound-method.md b/packages/eslint-plugin/docs/rules/unbound-method.md index 9f71738f5a91..b42e274ec59b 100644 --- a/packages/eslint-plugin/docs/rules/unbound-method.md +++ b/packages/eslint-plugin/docs/rules/unbound-method.md @@ -1,11 +1,8 @@ -# `unbound-method` - -Enforces unbound methods are called with their expected scope. - -Warns when a method is used outside of a method call. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/unbound-method** for documentation. Class functions don't preserve the class scope when passed as standalone variables. - If your function does not access `this`, [you can annotate it with `this: void`](https://www.typescriptlang.org/docs/handbook/2/functions.html#declaring-this-in-a-function), or consider using an arrow function instead. If you're working with `jest`, you can use [`eslint-plugin-jest`'s version of this rule](https://github.com/jest-community/eslint-plugin-jest/blob/main/docs/rules/unbound-method.md) to lint your test files, which knows when it's ok to pass an unbound method to `expect` calls. diff --git a/packages/eslint-plugin/docs/rules/unified-signatures.md b/packages/eslint-plugin/docs/rules/unified-signatures.md index 7cb47574a145..290c3f337399 100644 --- a/packages/eslint-plugin/docs/rules/unified-signatures.md +++ b/packages/eslint-plugin/docs/rules/unified-signatures.md @@ -1,6 +1,6 @@ -# `unified-signatures` - -Disallows two overloads that could be unified into one with a union or an optional/rest parameter. +> πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘ +> +> See **https://typescript-eslint.io/rules/unified-signatures** for documentation. ## Rule Details diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 31400bd4af69..efde7c0bbbf9 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/eslint-plugin", - "version": "5.30.7", + "version": "5.31.0", "description": "TypeScript plugin for ESLint", "keywords": [ "eslint", @@ -44,9 +44,9 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/scope-manager": "5.30.7", - "@typescript-eslint/type-utils": "5.30.7", - "@typescript-eslint/utils": "5.30.7", + "@typescript-eslint/scope-manager": "5.31.0", + "@typescript-eslint/type-utils": "5.31.0", + "@typescript-eslint/utils": "5.31.0", "debug": "^4.3.4", "functional-red-black-tree": "^1.0.1", "ignore": "^5.2.0", diff --git a/packages/eslint-plugin/src/configs/README.md b/packages/eslint-plugin/src/configs/README.md deleted file mode 100644 index c440d3d61c50..000000000000 --- a/packages/eslint-plugin/src/configs/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Premade Configs - -This page has moved to [docs/linting/CONFIGS.md](../../../../docs/linting/CONFIGS.md). diff --git a/packages/eslint-plugin/src/rules/consistent-generic-constructors.ts b/packages/eslint-plugin/src/rules/consistent-generic-constructors.ts index 0df1412bd7bb..db95efa9a57c 100644 --- a/packages/eslint-plugin/src/rules/consistent-generic-constructors.ts +++ b/packages/eslint-plugin/src/rules/consistent-generic-constructors.ts @@ -1,4 +1,4 @@ -import { AST_NODE_TYPES } from '@typescript-eslint/utils'; +import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/utils'; import { createRule } from '../util'; type MessageIds = 'preferTypeAnnotation' | 'preferConstructor'; @@ -30,9 +30,16 @@ export default createRule({ create(context, [mode]) { const sourceCode = context.getSourceCode(); return { - VariableDeclarator(node): void { - const lhs = node.id.typeAnnotation?.typeAnnotation; - const rhs = node.init; + 'VariableDeclarator,PropertyDefinition'( + node: TSESTree.VariableDeclarator | TSESTree.PropertyDefinition, + ): void { + const lhs = ( + node.type === AST_NODE_TYPES.VariableDeclarator ? node.id : node + ).typeAnnotation?.typeAnnotation; + const rhs = + node.type === AST_NODE_TYPES.VariableDeclarator + ? node.init + : node.value; if ( !rhs || rhs.type !== AST_NODE_TYPES.NewExpression || @@ -57,9 +64,25 @@ export default createRule({ node, messageId: 'preferTypeAnnotation', fix(fixer) { + function getIDToAttachAnnotation(): + | TSESTree.Token + | TSESTree.Node { + if (node.type === AST_NODE_TYPES.VariableDeclarator) { + return node.id; + } + if (!node.computed) { + return node.key; + } + // If the property's computed, we have to attach the + // annotation after the square bracket, not the enclosed expression + return sourceCode.getTokenAfter(node.key)!; + } return [ fixer.remove(typeParameters), - fixer.insertTextAfter(node.id, ': ' + typeAnnotation), + fixer.insertTextAfter( + getIDToAttachAnnotation(), + ': ' + typeAnnotation, + ), ]; }, }); diff --git a/packages/eslint-plugin/src/rules/prefer-nullish-coalescing.ts b/packages/eslint-plugin/src/rules/prefer-nullish-coalescing.ts index c1676d3fd323..b2321fd07570 100644 --- a/packages/eslint-plugin/src/rules/prefer-nullish-coalescing.ts +++ b/packages/eslint-plugin/src/rules/prefer-nullish-coalescing.ts @@ -5,14 +5,20 @@ import { TSESTree, } from '@typescript-eslint/utils'; import * as util from '../util'; +import * as ts from 'typescript'; export type Options = [ { ignoreConditionalTests?: boolean; + ignoreTernaryTests?: boolean; ignoreMixedLogicalExpressions?: boolean; }, ]; -export type MessageIds = 'preferNullish' | 'suggestNullish'; + +export type MessageIds = + | 'preferNullishOverOr' + | 'preferNullishOverTernary' + | 'suggestNullish'; export default util.createRule({ name: 'prefer-nullish-coalescing', @@ -27,8 +33,10 @@ export default util.createRule({ }, hasSuggestions: true, messages: { - preferNullish: + preferNullishOverOr: 'Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator.', + preferNullishOverTernary: + 'Prefer using nullish coalescing operator (`??`) instead of a ternary expression, as it is simpler to read.', suggestNullish: 'Fix to nullish coalescing operator (`??`).', }, schema: [ @@ -38,6 +46,9 @@ export default util.createRule({ ignoreConditionalTests: { type: 'boolean', }, + ignoreTernaryTests: { + type: 'boolean', + }, ignoreMixedLogicalExpressions: { type: 'boolean', }, @@ -52,15 +63,182 @@ export default util.createRule({ defaultOptions: [ { ignoreConditionalTests: true, + ignoreTernaryTests: true, ignoreMixedLogicalExpressions: true, }, ], - create(context, [{ ignoreConditionalTests, ignoreMixedLogicalExpressions }]) { + create( + context, + [ + { + ignoreConditionalTests, + ignoreTernaryTests, + ignoreMixedLogicalExpressions, + }, + ], + ) { const parserServices = util.getParserServices(context); const sourceCode = context.getSourceCode(); const checker = parserServices.program.getTypeChecker(); return { + ConditionalExpression(node: TSESTree.ConditionalExpression): void { + if (ignoreTernaryTests) { + return; + } + + let operator: '==' | '!=' | '===' | '!==' | undefined; + let nodesInsideTestExpression: TSESTree.Node[] = []; + if (node.test.type === AST_NODE_TYPES.BinaryExpression) { + nodesInsideTestExpression = [node.test.left, node.test.right]; + if ( + node.test.operator === '==' || + node.test.operator === '!=' || + node.test.operator === '===' || + node.test.operator === '!==' + ) { + operator = node.test.operator; + } + } else if ( + node.test.type === AST_NODE_TYPES.LogicalExpression && + node.test.left.type === AST_NODE_TYPES.BinaryExpression && + node.test.right.type === AST_NODE_TYPES.BinaryExpression + ) { + nodesInsideTestExpression = [ + node.test.left.left, + node.test.left.right, + node.test.right.left, + node.test.right.right, + ]; + if (node.test.operator === '||') { + if ( + node.test.left.operator === '===' && + node.test.right.operator === '===' + ) { + operator = '==='; + } else if ( + ((node.test.left.operator === '===' || + node.test.right.operator === '===') && + (node.test.left.operator === '==' || + node.test.right.operator === '==')) || + (node.test.left.operator === '==' && + node.test.right.operator === '==') + ) { + operator = '=='; + } + } else if (node.test.operator === '&&') { + if ( + node.test.left.operator === '!==' && + node.test.right.operator === '!==' + ) { + operator = '!=='; + } else if ( + ((node.test.left.operator === '!==' || + node.test.right.operator === '!==') && + (node.test.left.operator === '!=' || + node.test.right.operator === '!=')) || + (node.test.left.operator === '!=' && + node.test.right.operator === '!=') + ) { + operator = '!='; + } + } + } + + if (!operator) { + return; + } + + let identifier: TSESTree.Node | undefined; + let hasUndefinedCheck = false; + let hasNullCheck = false; + + // we check that the test only contains null, undefined and the identifier + for (const testNode of nodesInsideTestExpression) { + if (util.isNullLiteral(testNode)) { + hasNullCheck = true; + } else if (util.isUndefinedIdentifier(testNode)) { + hasUndefinedCheck = true; + } else if ( + (operator === '!==' || operator === '!=') && + util.isNodeEqual(testNode, node.consequent) + ) { + identifier = testNode; + } else if ( + (operator === '===' || operator === '==') && + util.isNodeEqual(testNode, node.alternate) + ) { + identifier = testNode; + } else { + return; + } + } + + if (!identifier) { + return; + } + + const isFixable = ((): boolean => { + // it is fixable if we check for both null and undefined, or not if neither + if (hasUndefinedCheck === hasNullCheck) { + return hasUndefinedCheck; + } + + // it is fixable if we loosely check for either null or undefined + if (operator === '==' || operator === '!=') { + return true; + } + + const tsNode = parserServices.esTreeNodeToTSNodeMap.get(identifier); + const type = checker.getTypeAtLocation(tsNode); + const flags = util.getTypeFlags(type); + + if (flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) { + return false; + } + + const hasNullType = (flags & ts.TypeFlags.Null) !== 0; + + // it is fixable if we check for undefined and the type is not nullable + if (hasUndefinedCheck && !hasNullType) { + return true; + } + + const hasUndefinedType = (flags & ts.TypeFlags.Undefined) !== 0; + + // it is fixable if we check for null and the type can't be undefined + return hasNullCheck && !hasUndefinedType; + })(); + + if (isFixable) { + context.report({ + node, + messageId: 'preferNullishOverTernary', + suggest: [ + { + messageId: 'suggestNullish', + fix(fixer: TSESLint.RuleFixer): TSESLint.RuleFix { + const [left, right] = + operator === '===' || operator === '==' + ? [node.alternate, node.consequent] + : [node.consequent, node.alternate]; + return fixer.replaceText( + node, + `${sourceCode.text.slice( + left.range[0], + left.range[1], + )} ?? ${sourceCode.text.slice( + right.range[0], + right.range[1], + )}`, + ); + }, + }, + ], + }); + } + }, + 'LogicalExpression[operator = "||"]'( node: TSESTree.LogicalExpression, ): void { @@ -110,7 +288,7 @@ export default util.createRule({ context.report({ node: barBarOperator, - messageId: 'preferNullish', + messageId: 'preferNullishOverOr', suggest: [ { messageId: 'suggestNullish', diff --git a/packages/eslint-plugin/src/rules/prefer-optional-chain.ts b/packages/eslint-plugin/src/rules/prefer-optional-chain.ts index 04cd7e649933..662439ac743a 100644 --- a/packages/eslint-plugin/src/rules/prefer-optional-chain.ts +++ b/packages/eslint-plugin/src/rules/prefer-optional-chain.ts @@ -437,24 +437,10 @@ function isValidChainTarget( - foo !== undefined - foo != undefined */ - if ( + return ( node.type === AST_NODE_TYPES.BinaryExpression && ['!==', '!='].includes(node.operator) && - isValidChainTarget(node.left, allowIdentifier) - ) { - if ( - node.right.type === AST_NODE_TYPES.Identifier && - node.right.name === 'undefined' - ) { - return true; - } - if ( - node.right.type === AST_NODE_TYPES.Literal && - node.right.value === null - ) { - return true; - } - } - - return false; + isValidChainTarget(node.left, allowIdentifier) && + (util.isUndefinedIdentifier(node.right) || util.isNullLiteral(node.right)) + ); } diff --git a/packages/eslint-plugin/src/rules/typedef.ts b/packages/eslint-plugin/src/rules/typedef.ts index a995fe41b37f..4f5fe6eae654 100644 --- a/packages/eslint-plugin/src/rules/typedef.ts +++ b/packages/eslint-plugin/src/rules/typedef.ts @@ -150,13 +150,14 @@ export default util.createRule<[Options], MessageIds>({ } function isAncestorHasTypeAnnotation( - node: TSESTree.ObjectPattern, + node: TSESTree.ObjectPattern | TSESTree.ArrayPattern, ): boolean { let ancestor = node.parent; while (ancestor) { if ( - ancestor.type === AST_NODE_TYPES.ObjectPattern && + (ancestor.type === AST_NODE_TYPES.ObjectPattern || + ancestor.type === AST_NODE_TYPES.ArrayPattern) && ancestor.typeAnnotation ) { return true; @@ -181,6 +182,7 @@ export default util.createRule<[Options], MessageIds>({ if ( !node.typeAnnotation && !isForOfStatementContext(node) && + !isAncestorHasTypeAnnotation(node) && node.parent?.type !== AST_NODE_TYPES.AssignmentExpression ) { report(node); diff --git a/packages/eslint-plugin/src/util/index.ts b/packages/eslint-plugin/src/util/index.ts index b2932466388d..98ef1cf87076 100644 --- a/packages/eslint-plugin/src/util/index.ts +++ b/packages/eslint-plugin/src/util/index.ts @@ -9,6 +9,9 @@ export * from './getThisExpression'; export * from './getWrappingFixer'; export * from './misc'; export * from './objectIterators'; +export * from './isNullLiteral'; +export * from './isUndefinedIdentifier'; +export * from './isNodeEqual'; // this is done for convenience - saves migrating all of the old rules export * from '@typescript-eslint/type-utils'; diff --git a/packages/eslint-plugin/src/util/isNodeEqual.ts b/packages/eslint-plugin/src/util/isNodeEqual.ts new file mode 100644 index 000000000000..ef879163ee44 --- /dev/null +++ b/packages/eslint-plugin/src/util/isNodeEqual.ts @@ -0,0 +1,31 @@ +import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/utils'; + +export function isNodeEqual(a: TSESTree.Node, b: TSESTree.Node): boolean { + if (a.type !== b.type) { + return false; + } + if ( + a.type === AST_NODE_TYPES.ThisExpression && + b.type === AST_NODE_TYPES.ThisExpression + ) { + return true; + } + if (a.type === AST_NODE_TYPES.Literal && b.type === AST_NODE_TYPES.Literal) { + return a.value === b.value; + } + if ( + a.type === AST_NODE_TYPES.Identifier && + b.type === AST_NODE_TYPES.Identifier + ) { + return a.name === b.name; + } + if ( + a.type === AST_NODE_TYPES.MemberExpression && + b.type === AST_NODE_TYPES.MemberExpression + ) { + return ( + isNodeEqual(a.property, b.property) && isNodeEqual(a.object, b.object) + ); + } + return false; +} diff --git a/packages/eslint-plugin/src/util/isNullLiteral.ts b/packages/eslint-plugin/src/util/isNullLiteral.ts new file mode 100644 index 000000000000..e700e415f636 --- /dev/null +++ b/packages/eslint-plugin/src/util/isNullLiteral.ts @@ -0,0 +1,5 @@ +import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/utils'; + +export function isNullLiteral(i: TSESTree.Node): boolean { + return i.type === AST_NODE_TYPES.Literal && i.value === null; +} diff --git a/packages/eslint-plugin/src/util/isUndefinedIdentifier.ts b/packages/eslint-plugin/src/util/isUndefinedIdentifier.ts new file mode 100644 index 000000000000..91cae07aa814 --- /dev/null +++ b/packages/eslint-plugin/src/util/isUndefinedIdentifier.ts @@ -0,0 +1,5 @@ +import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/utils'; + +export function isUndefinedIdentifier(i: TSESTree.Node): boolean { + return i.type === AST_NODE_TYPES.Identifier && i.name === 'undefined'; +} diff --git a/packages/eslint-plugin/tests/docs.test.ts b/packages/eslint-plugin/tests/docs.test.ts index 13262e4ce73c..7ab1095f4ad0 100644 --- a/packages/eslint-plugin/tests/docs.test.ts +++ b/packages/eslint-plugin/tests/docs.test.ts @@ -41,10 +41,6 @@ function tokenIs( return token.type === type; } -function tokenIsH1(token: marked.Token): token is marked.Tokens.Heading { - return tokenIs(token, 'heading') && token.depth === 1; -} - function tokenIsH2(token: marked.Token): token is marked.Tokens.Heading { return tokenIs(token, 'heading') && token.depth === 2; } @@ -71,26 +67,17 @@ describe('Validating rule docs', () => { describe(ruleName, () => { const filePath = path.join(docsRoot, `${ruleName}.md`); - it(`First header in ${ruleName}.md must be the name of the rule`, () => { - const tokens = parseMarkdownFile(filePath); - - const header = tokens.find(tokenIsH1)!; - - expect(header.text).toBe(`\`${ruleName}\``); - }); - - it(`Description of ${ruleName}.md must match`, () => { - // validate if description of rule is same as in docs + test(`${ruleName}.md must start with blockquote directing to website`, () => { const tokens = parseMarkdownFile(filePath); - // Rule title not found. - // Rule title does not match the rule metadata. - expect(tokens[1]).toMatchObject({ - type: 'paragraph', - text: `${rule.meta.docs?.description.replace( - /(? = Foo();', 'const a: Foo = Foo();', 'const a: Foo = Foo();', + ` +class Foo { + a = new Foo(); +} + `, // type-annotation { code: 'const a = new Foo();', @@ -60,6 +65,14 @@ ruleTester.run('consistent-generic-constructors', rule, { code: 'const a = new (class C {})();', options: ['type-annotation'], }, + { + code: ` +class Foo { + a: Foo = new Foo(); +} + `, + options: ['type-annotation'], + }, ], invalid: [ { @@ -143,6 +156,40 @@ ruleTester.run('consistent-generic-constructors', rule, { ], output: noFormat`const a = new \n Foo \n ();`, }, + { + code: ` +class Foo { + a: Foo = new Foo(); +} + `, + errors: [ + { + messageId: 'preferConstructor', + }, + ], + output: ` +class Foo { + a = new Foo(); +} + `, + }, + { + code: ` +class Foo { + [a]: Foo = new Foo(); +} + `, + errors: [ + { + messageId: 'preferConstructor', + }, + ], + output: ` +class Foo { + [a] = new Foo(); +} + `, + }, { code: 'const a = new Foo();', options: ['type-annotation'], @@ -213,5 +260,59 @@ ruleTester.run('consistent-generic-constructors', rule, { ], output: noFormat`const a: Foo = new Foo();`, }, + { + code: ` +class Foo { + a = new Foo(); +} + `, + options: ['type-annotation'], + errors: [ + { + messageId: 'preferTypeAnnotation', + }, + ], + output: ` +class Foo { + a: Foo = new Foo(); +} + `, + }, + { + code: ` +class Foo { + [a] = new Foo(); +} + `, + options: ['type-annotation'], + errors: [ + { + messageId: 'preferTypeAnnotation', + }, + ], + output: ` +class Foo { + [a]: Foo = new Foo(); +} + `, + }, + { + code: ` +class Foo { + [a + b] = new Foo(); +} + `, + options: ['type-annotation'], + errors: [ + { + messageId: 'preferTypeAnnotation', + }, + ], + output: ` +class Foo { + [a + b]: Foo = new Foo(); +} + `, + }, ], }); diff --git a/packages/eslint-plugin/tests/rules/no-unused-vars/no-unused-vars.test.ts b/packages/eslint-plugin/tests/rules/no-unused-vars/no-unused-vars.test.ts index 362466ee1a0f..5fac3eeed71a 100644 --- a/packages/eslint-plugin/tests/rules/no-unused-vars/no-unused-vars.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unused-vars/no-unused-vars.test.ts @@ -921,6 +921,15 @@ export declare namespace Foo { } } } + `, + noFormat` +class Foo { + value: T; +} +class Bar { + foo = Foo; +} +new Bar(); `, { code: ` diff --git a/packages/eslint-plugin/tests/rules/prefer-nullish-coalescing.test.ts b/packages/eslint-plugin/tests/rules/prefer-nullish-coalescing.test.ts index 8096df94c329..55fb4452973b 100644 --- a/packages/eslint-plugin/tests/rules/prefer-nullish-coalescing.test.ts +++ b/packages/eslint-plugin/tests/rules/prefer-nullish-coalescing.test.ts @@ -71,6 +71,71 @@ x ?? 'foo'; `, ), + { + code: 'x !== undefined && x !== null ? x : y;', + options: [{ ignoreTernaryTests: true }], + }, + + ...[ + 'x !== undefined && x !== null ? "foo" : "bar";', + 'x !== null && x !== undefined && x !== 5 ? x : y', + 'x === null || x === undefined || x === 5 ? x : y', + 'x === undefined && x !== null ? x : y;', + 'x === undefined && x === null ? x : y;', + 'x !== undefined && x === null ? x : y;', + 'x === undefined || x !== null ? x : y;', + 'x === undefined || x === null ? x : y;', + 'x !== undefined || x === null ? x : y;', + 'x !== undefined || x === null ? y : x;', + 'x === null || x === null ? y : x;', + 'x === undefined || x === undefined ? y : x;', + 'x == null ? x : y;', + 'undefined == null ? x : y;', + 'undefined != z ? x : y;', + 'x == undefined ? x : y;', + 'x != null ? y : x;', + 'x != undefined ? y : x;', + 'null == x ? x : y;', + 'undefined == x ? x : y;', + 'null != x ? y : x;', + 'undefined != x ? y : x;', + ` +declare const x: string; +x === null ? x : y; + `, + ` +declare const x: string | undefined; +x === null ? x : y; + `, + ` +declare const x: string | null; +x === undefined ? x : y; + `, + ` +declare const x: string | undefined | null; +x !== undefined ? x : y; + `, + ` +declare const x: string | undefined | null; +x !== null ? x : y; + `, + ` +declare const x: string | null | any; +x === null ? x : y; + `, + ` +declare const x: string | null | unknown; +x === null ? x : y; + `, + ` +declare const x: string | undefined; +x === null ? x : y; + `, + ].map(code => ({ + code, + options: [{ ignoreTernaryTests: false }] as const, + })), + // ignoreConditionalTests ...nullishTypeValidTest((nullish, type) => ({ code: ` @@ -148,7 +213,7 @@ x || 'foo'; output: null, errors: [ { - messageId: 'preferNullish', + messageId: 'preferNullishOverOr', line: 3, column: 3, endLine: 3, @@ -166,6 +231,158 @@ x ?? 'foo'; ], })), + ...[ + 'x !== undefined && x !== null ? x : y;', + 'x !== null && x !== undefined ? x : y;', + 'x === undefined || x === null ? y : x;', + 'x === null || x === undefined ? y : x;', + 'undefined !== x && x !== null ? x : y;', + 'null !== x && x !== undefined ? x : y;', + 'undefined === x || x === null ? y : x;', + 'null === x || x === undefined ? y : x;', + 'x !== undefined && null !== x ? x : y;', + 'x !== null && undefined !== x ? x : y;', + 'x === undefined || null === x ? y : x;', + 'x === null || undefined === x ? y : x;', + 'undefined !== x && null !== x ? x : y;', + 'null !== x && undefined !== x ? x : y;', + 'undefined === x || null === x ? y : x;', + 'null === x || undefined === x ? y : x;', + 'x != undefined && x != null ? x : y;', + 'x == undefined || x == null ? y : x;', + 'x != undefined && x !== null ? x : y;', + 'x == undefined || x === null ? y : x;', + 'x !== undefined && x != null ? x : y;', + 'undefined != x ? x : y;', + 'null != x ? x : y;', + 'undefined == x ? y : x;', + 'null == x ? y : x;', + 'x != undefined ? x : y;', + 'x != null ? x : y;', + 'x == undefined ? y : x;', + 'x == null ? y : x;', + ].flatMap(code => [ + { + code, + output: null, + options: [{ ignoreTernaryTests: false }] as const, + errors: [ + { + messageId: 'preferNullishOverTernary' as const, + line: 1, + column: 1, + endLine: 1, + endColumn: code.length, + suggestions: [ + { + messageId: 'suggestNullish' as const, + output: 'x ?? y;', + }, + ], + }, + ], + }, + { + code: code.replace(/x/g, 'x.z[1][this[this.o]]["3"][a.b.c]'), + output: null, + options: [{ ignoreTernaryTests: false }] as const, + errors: [ + { + messageId: 'preferNullishOverTernary' as const, + line: 1, + column: 1, + endLine: 1, + endColumn: code.replace(/x/g, 'x.z[1][this[this.o]]["3"][a.b.c]') + .length, + suggestions: [ + { + messageId: 'suggestNullish' as const, + output: 'x.z[1][this[this.o]]["3"][a.b.c] ?? y;', + }, + ], + }, + ], + }, + ]), + + { + code: 'this != undefined ? this : y;', + output: null, + options: [{ ignoreTernaryTests: false }] as const, + errors: [ + { + messageId: 'preferNullishOverTernary' as const, + line: 1, + column: 1, + endLine: 1, + endColumn: 29, + suggestions: [ + { + messageId: 'suggestNullish' as const, + output: 'this ?? y;', + }, + ], + }, + ], + }, + + ...[ + ` +declare const x: string | undefined; +x !== undefined ? x : y; + `.trim(), + ` +declare const x: string | undefined; +undefined !== x ? x : y; + `.trim(), + ` +declare const x: string | undefined; +undefined === x ? y : x; + `.trim(), + ` +declare const x: string | undefined; +undefined === x ? y : x; + `.trim(), + ` +declare const x: string | null; +x !== null ? x : y; + `.trim(), + ` +declare const x: string | null; +null !== x ? x : y; + `.trim(), + ` +declare const x: string | null; +null === x ? y : x; + `.trim(), + ` +declare const x: string | null; +null === x ? y : x; + `.trim(), + ].map(code => ({ + code, + output: null, + options: [{ ignoreTernaryTests: false }] as const, + errors: [ + { + messageId: 'preferNullishOverTernary' as const, + line: 2, + column: 1, + endLine: 2, + endColumn: code.split('\n')[1].length, + suggestions: [ + { + messageId: 'suggestNullish' as const, + output: ` +${code.split('\n')[0]} +x ?? y; + `.trim(), + }, + ], + }, + ], + })), + // ignoreConditionalTests ...nullishTypeInvalidTest((nullish, type) => ({ code: ` @@ -176,7 +393,7 @@ x || 'foo' ? null : null; options: [{ ignoreConditionalTests: false }], errors: [ { - messageId: 'preferNullish', + messageId: 'preferNullishOverOr', line: 3, column: 3, endLine: 3, @@ -202,7 +419,7 @@ if (x || 'foo') {} options: [{ ignoreConditionalTests: false }], errors: [ { - messageId: 'preferNullish', + messageId: 'preferNullishOverOr', line: 3, column: 7, endLine: 3, @@ -228,7 +445,7 @@ do {} while (x || 'foo') options: [{ ignoreConditionalTests: false }], errors: [ { - messageId: 'preferNullish', + messageId: 'preferNullishOverOr', line: 3, column: 16, endLine: 3, @@ -254,7 +471,7 @@ for (;x || 'foo';) {} options: [{ ignoreConditionalTests: false }], errors: [ { - messageId: 'preferNullish', + messageId: 'preferNullishOverOr', line: 3, column: 9, endLine: 3, @@ -280,7 +497,7 @@ while (x || 'foo') {} options: [{ ignoreConditionalTests: false }], errors: [ { - messageId: 'preferNullish', + messageId: 'preferNullishOverOr', line: 3, column: 10, endLine: 3, @@ -309,7 +526,7 @@ a || b && c; options: [{ ignoreMixedLogicalExpressions: false }], errors: [ { - messageId: 'preferNullish', + messageId: 'preferNullishOverOr', line: 5, column: 3, endLine: 5, @@ -339,7 +556,7 @@ a || b || c && d; options: [{ ignoreMixedLogicalExpressions: false }], errors: [ { - messageId: 'preferNullish', + messageId: 'preferNullishOverOr', line: 6, column: 3, endLine: 6, @@ -358,7 +575,7 @@ declare const d: ${type} | ${nullish}; ], }, { - messageId: 'preferNullish', + messageId: 'preferNullishOverOr', line: 6, column: 8, endLine: 6, @@ -389,7 +606,7 @@ a && b || c || d; options: [{ ignoreMixedLogicalExpressions: false }], errors: [ { - messageId: 'preferNullish', + messageId: 'preferNullishOverOr', line: 6, column: 8, endLine: 6, @@ -408,7 +625,7 @@ a && (b ?? c) || d; ], }, { - messageId: 'preferNullish', + messageId: 'preferNullishOverOr', line: 6, column: 13, endLine: 6, @@ -439,7 +656,7 @@ if (() => x || 'foo') {} options: [{ ignoreConditionalTests: true }], errors: [ { - messageId: 'preferNullish', + messageId: 'preferNullishOverOr', line: 3, column: 13, endLine: 3, @@ -465,7 +682,7 @@ if (function werid() { return x || 'foo' }) {} options: [{ ignoreConditionalTests: true }], errors: [ { - messageId: 'preferNullish', + messageId: 'preferNullishOverOr', line: 3, column: 33, endLine: 3, @@ -482,7 +699,6 @@ if (function werid() { return x ?? 'foo' }) {} }, ], })), - // https://github.com/typescript-eslint/typescript-eslint/issues/1290 ...nullishTypeInvalidTest((nullish, type) => ({ code: ` @@ -494,7 +710,7 @@ a || b || c; output: null, errors: [ { - messageId: 'preferNullish', + messageId: 'preferNullishOverOr', line: 5, column: 3, endLine: 5, diff --git a/packages/eslint-plugin/tests/rules/typedef.test.ts b/packages/eslint-plugin/tests/rules/typedef.test.ts index 19b6ff5a543b..d6f724bfd0b4 100644 --- a/packages/eslint-plugin/tests/rules/typedef.test.ts +++ b/packages/eslint-plugin/tests/rules/typedef.test.ts @@ -70,6 +70,32 @@ ruleTester.run('typedef', rule, { }, ], }, + { + code: 'const [[a]]: number[][] = [[1]];', + options: [ + { + arrayDestructuring: true, + }, + ], + }, + { + code: 'const foo = ([{ bar }]: { bar: string }[]) => {};', + options: [ + { + arrayDestructuring: true, + objectDestructuring: true, + }, + ], + }, + { + code: 'const foo = ([{ bar }]: [{ bar: string }]) => {};', + options: [ + { + arrayDestructuring: true, + objectDestructuring: true, + }, + ], + }, { code: 'const [a] = [1];', options: [ diff --git a/packages/eslint-plugin/tests/util/isNodeEqual.test.ts b/packages/eslint-plugin/tests/util/isNodeEqual.test.ts new file mode 100644 index 000000000000..76da9eabdb42 --- /dev/null +++ b/packages/eslint-plugin/tests/util/isNodeEqual.test.ts @@ -0,0 +1,106 @@ +import { TSESTree, TSESLint } from '@typescript-eslint/utils'; +import { getFixturesRootDir, RuleTester } from '../RuleTester'; +import { createRule, isNodeEqual } from '../../src/util'; + +const rule = createRule({ + name: 'no-useless-expression', + defaultOptions: [], + meta: { + type: 'suggestion', + fixable: 'code', + docs: { + description: 'Remove useless expressions.', + recommended: false, + }, + messages: { + removeExpression: 'Remove useless expression', + }, + schema: [], + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + return { + LogicalExpression: (node: TSESTree.LogicalExpression): void => { + if ( + (node.operator === '??' || + node.operator === '||' || + node.operator === '&&') && + isNodeEqual(node.left, node.right) + ) { + context.report({ + node, + messageId: 'removeExpression', + fix(fixer: TSESLint.RuleFixer): TSESLint.RuleFix { + return fixer.replaceText( + node, + sourceCode.text.slice(node.left.range[0], node.left.range[1]), + ); + }, + }); + } + }, + }; + }, +}); + +const rootPath = getFixturesRootDir(); +const ruleTester = new RuleTester({ + parser: '@typescript-eslint/parser', + parserOptions: { + tsconfigRootDir: rootPath, + project: './tsconfig.json', + }, +}); + +ruleTester.run('isNodeEqual', rule, { + valid: [ + { code: 'a || b' }, + { code: '!true || true' }, + { code: 'a() || a()' }, + { code: 'foo.bar || foo.bar.foo' }, + ], + invalid: [ + { + code: 'undefined || undefined', + errors: [{ messageId: 'removeExpression' }], + output: 'undefined', + }, + { + code: 'true && true', + errors: [{ messageId: 'removeExpression' }], + output: 'true', + }, + { + code: 'a || a', + errors: [{ messageId: 'removeExpression' }], + output: 'a', + }, + { + code: 'a && a', + errors: [{ messageId: 'removeExpression' }], + output: 'a', + }, + { + code: 'a ?? a', + errors: [{ messageId: 'removeExpression' }], + output: 'a', + }, + { + code: 'foo.bar || foo.bar', + errors: [{ messageId: 'removeExpression' }], + output: 'foo.bar', + }, + { + code: 'this.foo.bar || this.foo.bar', + errors: [{ messageId: 'removeExpression' }], + output: 'this.foo.bar', + }, + { + code: 'x.z[1][this[this.o]]["3"][a.b.c] || x.z[1][this[this.o]]["3"][a.b.c]', + errors: [{ messageId: 'removeExpression' }], + output: 'x.z[1][this[this.o]]["3"][a.b.c]', + }, + ], +}); diff --git a/packages/experimental-utils/CHANGELOG.md b/packages/experimental-utils/CHANGELOG.md index d692cba00b5a..bcbfe2782b05 100644 --- a/packages/experimental-utils/CHANGELOG.md +++ b/packages/experimental-utils/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.31.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.30.7...v5.31.0) (2022-07-25) + +**Note:** Version bump only for package @typescript-eslint/experimental-utils + + + + + ## [5.30.7](https://github.com/typescript-eslint/typescript-eslint/compare/v5.30.6...v5.30.7) (2022-07-18) **Note:** Version bump only for package @typescript-eslint/experimental-utils diff --git a/packages/experimental-utils/package.json b/packages/experimental-utils/package.json index 6bb61a494d7a..b7d3d70cda79 100644 --- a/packages/experimental-utils/package.json +++ b/packages/experimental-utils/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/experimental-utils", - "version": "5.30.7", + "version": "5.31.0", "description": "(Experimental) Utilities for working with TypeScript + ESLint together", "keywords": [ "eslint", @@ -38,7 +38,7 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/utils": "5.30.7" + "@typescript-eslint/utils": "5.31.0" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" diff --git a/packages/parser/CHANGELOG.md b/packages/parser/CHANGELOG.md index 76871eb2767b..1827897fa5f9 100644 --- a/packages/parser/CHANGELOG.md +++ b/packages/parser/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.31.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.30.7...v5.31.0) (2022-07-25) + +**Note:** Version bump only for package @typescript-eslint/parser + + + + + ## [5.30.7](https://github.com/typescript-eslint/typescript-eslint/compare/v5.30.6...v5.30.7) (2022-07-18) diff --git a/packages/parser/README.md b/packages/parser/README.md index 018935b2ca9f..3488cd5e5052 100644 --- a/packages/parser/README.md +++ b/packages/parser/README.md @@ -256,7 +256,7 @@ Note that if you pass custom programs via `options.programs` this option will no Default `undefined`. -This option allow you to tell parser to act as if `emitDecoratorMetadata: true` is set in `tsconfig.json`, but without [type-aware linting](https://typescript-eslint.io/docs/linting/type-linting). In other words, you don't have to specify `parserOptions.project` in this case, making the linting process faster. +This option allow you to tell parser to act as if `emitDecoratorMetadata: true` is set in `tsconfig.json`, but without [type-aware linting](https://typescript-eslint.io/docs/linting/typed-linting). In other words, you don't have to specify `parserOptions.project` in this case, making the linting process faster. ## Utilities diff --git a/packages/parser/package.json b/packages/parser/package.json index a7a70ae2acf4..a7a34bbdb921 100644 --- a/packages/parser/package.json +++ b/packages/parser/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/parser", - "version": "5.30.7", + "version": "5.31.0", "description": "An ESLint custom parser which leverages TypeScript ESTree", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -45,9 +45,9 @@ "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "dependencies": { - "@typescript-eslint/scope-manager": "5.30.7", - "@typescript-eslint/types": "5.30.7", - "@typescript-eslint/typescript-estree": "5.30.7", + "@typescript-eslint/scope-manager": "5.31.0", + "@typescript-eslint/types": "5.31.0", + "@typescript-eslint/typescript-estree": "5.31.0", "debug": "^4.3.4" }, "devDependencies": { diff --git a/packages/scope-manager/CHANGELOG.md b/packages/scope-manager/CHANGELOG.md index b280a087c073..8c1b32a851ce 100644 --- a/packages/scope-manager/CHANGELOG.md +++ b/packages/scope-manager/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.31.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.30.7...v5.31.0) (2022-07-25) + + +### Bug Fixes + +* **scope-manager:** handle typeParameters of TSInstantiationExpression ([#5355](https://github.com/typescript-eslint/typescript-eslint/issues/5355)) ([2595ccf](https://github.com/typescript-eslint/typescript-eslint/commit/2595ccf67cd5158edbd6bebd9ac2dbd8bbd8b99c)) + + + + + ## [5.30.7](https://github.com/typescript-eslint/typescript-eslint/compare/v5.30.6...v5.30.7) (2022-07-18) diff --git a/packages/scope-manager/package.json b/packages/scope-manager/package.json index 60281382536a..cf66eeae3e34 100644 --- a/packages/scope-manager/package.json +++ b/packages/scope-manager/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/scope-manager", - "version": "5.30.7", + "version": "5.31.0", "description": "TypeScript scope analyser for ESLint", "keywords": [ "eslint", @@ -38,12 +38,12 @@ "typecheck": "cd ../../ && nx typecheck @typescript-eslint/scope-manager" }, "dependencies": { - "@typescript-eslint/types": "5.30.7", - "@typescript-eslint/visitor-keys": "5.30.7" + "@typescript-eslint/types": "5.31.0", + "@typescript-eslint/visitor-keys": "5.31.0" }, "devDependencies": { "@types/glob": "*", - "@typescript-eslint/typescript-estree": "5.30.7", + "@typescript-eslint/typescript-estree": "5.31.0", "glob": "*", "jest-specific-snapshot": "*", "make-dir": "*", diff --git a/packages/scope-manager/src/referencer/Referencer.ts b/packages/scope-manager/src/referencer/Referencer.ts index 3190af3a56cd..84b0d96a2555 100644 --- a/packages/scope-manager/src/referencer/Referencer.ts +++ b/packages/scope-manager/src/referencer/Referencer.ts @@ -692,6 +692,13 @@ class Referencer extends Visitor { this.close(node); } + protected TSInstantiationExpression( + node: TSESTree.TSInstantiationExpression, + ): void { + this.visitChildren(node, ['typeParameters']); + this.visitType(node.typeParameters); + } + protected TSInterfaceDeclaration( node: TSESTree.TSInterfaceDeclaration, ): void { diff --git a/packages/scope-manager/tests/fixtures/instantiation-expressions/type-arguments1.ts b/packages/scope-manager/tests/fixtures/instantiation-expressions/type-arguments1.ts new file mode 100644 index 000000000000..dc8e0419db77 --- /dev/null +++ b/packages/scope-manager/tests/fixtures/instantiation-expressions/type-arguments1.ts @@ -0,0 +1,9 @@ +class Foo { + value: T +} + +class Bar { + foo = Foo +} + +new Bar() diff --git a/packages/scope-manager/tests/fixtures/instantiation-expressions/type-arguments1.ts.shot b/packages/scope-manager/tests/fixtures/instantiation-expressions/type-arguments1.ts.shot new file mode 100644 index 000000000000..4b22bb095c80 --- /dev/null +++ b/packages/scope-manager/tests/fixtures/instantiation-expressions/type-arguments1.ts.shot @@ -0,0 +1,182 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`instantiation-expressions type-arguments1 1`] = ` +ScopeManager { + variables: Array [ + ImplicitGlobalConstTypeVariable, + Variable$2 { + defs: Array [ + ClassNameDefinition$1 { + name: Identifier<"Foo">, + node: ClassDeclaration$1, + }, + ], + name: "Foo", + references: Array [ + Reference$2 { + identifier: Identifier<"Foo">, + isRead: true, + isTypeReference: false, + isValueReference: true, + isWrite: false, + resolved: Variable$2, + }, + ], + isValueVariable: true, + isTypeVariable: true, + }, + Variable$3 { + defs: Array [ + ClassNameDefinition$2 { + name: Identifier<"Foo">, + node: ClassDeclaration$1, + }, + ], + name: "Foo", + references: Array [], + isValueVariable: true, + isTypeVariable: true, + }, + Variable$4 { + defs: Array [ + TypeDefinition$3 { + name: Identifier<"T">, + node: TSTypeParameter$2, + }, + ], + name: "T", + references: Array [ + Reference$1 { + identifier: Identifier<"T">, + isRead: true, + isTypeReference: true, + isValueReference: false, + isWrite: false, + resolved: Variable$4, + }, + ], + isValueVariable: false, + isTypeVariable: true, + }, + Variable$5 { + defs: Array [ + ClassNameDefinition$4 { + name: Identifier<"Bar">, + node: ClassDeclaration$3, + }, + ], + name: "Bar", + references: Array [ + Reference$4 { + identifier: Identifier<"Bar">, + isRead: true, + isTypeReference: false, + isValueReference: true, + isWrite: false, + resolved: Variable$5, + }, + ], + isValueVariable: true, + isTypeVariable: true, + }, + Variable$6 { + defs: Array [ + ClassNameDefinition$5 { + name: Identifier<"Bar">, + node: ClassDeclaration$3, + }, + ], + name: "Bar", + references: Array [], + isValueVariable: true, + isTypeVariable: true, + }, + Variable$7 { + defs: Array [ + TypeDefinition$6 { + name: Identifier<"T">, + node: TSTypeParameter$4, + }, + ], + name: "T", + references: Array [ + Reference$3 { + identifier: Identifier<"T">, + isRead: true, + isTypeReference: true, + isValueReference: false, + isWrite: false, + resolved: Variable$7, + }, + ], + isValueVariable: false, + isTypeVariable: true, + }, + ], + scopes: Array [ + GlobalScope$1 { + block: Program$5, + isStrict: false, + references: Array [ + Reference$4, + ], + set: Map { + "const" => ImplicitGlobalConstTypeVariable, + "Foo" => Variable$2, + "Bar" => Variable$5, + }, + type: "global", + upper: null, + variables: Array [ + ImplicitGlobalConstTypeVariable, + Variable$2, + Variable$5, + ], + }, + ClassScope$2 { + block: ClassDeclaration$1, + isStrict: true, + references: Array [ + Reference$1, + ], + set: Map { + "Foo" => Variable$3, + "T" => Variable$4, + }, + type: "class", + upper: GlobalScope$1, + variables: Array [ + Variable$3, + Variable$4, + ], + }, + ClassScope$3 { + block: ClassDeclaration$3, + isStrict: true, + references: Array [], + set: Map { + "Bar" => Variable$6, + "T" => Variable$7, + }, + type: "class", + upper: GlobalScope$1, + variables: Array [ + Variable$6, + Variable$7, + ], + }, + ClassFieldInitializerScope$4 { + block: TSInstantiationExpression$6, + isStrict: true, + references: Array [ + Reference$2, + Reference$3, + ], + set: Map {}, + type: "class-field-initializer", + upper: ClassScope$3, + variables: Array [], + }, + ], +} +`; diff --git a/packages/scope-manager/tests/fixtures/instantiation-expressions/type-arguments2.ts b/packages/scope-manager/tests/fixtures/instantiation-expressions/type-arguments2.ts new file mode 100644 index 000000000000..a2f0d23446cd --- /dev/null +++ b/packages/scope-manager/tests/fixtures/instantiation-expressions/type-arguments2.ts @@ -0,0 +1,6 @@ +function makeBox(value: T) { + return { value }; +} + +type BoxFunc = typeof makeBox; +const makeStringBox = makeBox; diff --git a/packages/scope-manager/tests/fixtures/instantiation-expressions/type-arguments2.ts.shot b/packages/scope-manager/tests/fixtures/instantiation-expressions/type-arguments2.ts.shot new file mode 100644 index 000000000000..e2f0a03503c7 --- /dev/null +++ b/packages/scope-manager/tests/fixtures/instantiation-expressions/type-arguments2.ts.shot @@ -0,0 +1,203 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`instantiation-expressions type-arguments2 1`] = ` +ScopeManager { + variables: Array [ + ImplicitGlobalConstTypeVariable, + Variable$2 { + defs: Array [ + FunctionNameDefinition$1 { + name: Identifier<"makeBox">, + node: FunctionDeclaration$1, + }, + ], + name: "makeBox", + references: Array [ + Reference$3 { + identifier: Identifier<"makeBox">, + isRead: true, + isTypeReference: false, + isValueReference: true, + isWrite: false, + resolved: Variable$2, + }, + Reference$6 { + identifier: Identifier<"makeBox">, + isRead: true, + isTypeReference: false, + isValueReference: true, + isWrite: false, + resolved: Variable$2, + }, + ], + isValueVariable: true, + isTypeVariable: false, + }, + Variable$3 { + defs: Array [], + name: "arguments", + references: Array [], + isValueVariable: true, + isTypeVariable: true, + }, + Variable$4 { + defs: Array [ + ParameterDefinition$2 { + name: Identifier<"value">, + node: FunctionDeclaration$1, + }, + ], + name: "value", + references: Array [ + Reference$2 { + identifier: Identifier<"value">, + isRead: true, + isTypeReference: false, + isValueReference: true, + isWrite: false, + resolved: Variable$4, + }, + ], + isValueVariable: true, + isTypeVariable: false, + }, + Variable$5 { + defs: Array [ + TypeDefinition$3 { + name: Identifier<"T">, + node: TSTypeParameter$2, + }, + ], + name: "T", + references: Array [ + Reference$1 { + identifier: Identifier<"T">, + isRead: true, + isTypeReference: true, + isValueReference: false, + isWrite: false, + resolved: Variable$5, + }, + ], + isValueVariable: false, + isTypeVariable: true, + }, + Variable$6 { + defs: Array [ + TypeDefinition$4 { + name: Identifier<"BoxFunc">, + node: TSTypeAliasDeclaration$3, + }, + ], + name: "BoxFunc", + references: Array [], + isValueVariable: false, + isTypeVariable: true, + }, + Variable$7 { + defs: Array [ + TypeDefinition$5 { + name: Identifier<"T">, + node: TSTypeParameter$4, + }, + ], + name: "T", + references: Array [ + Reference$4 { + identifier: Identifier<"T">, + isRead: true, + isTypeReference: true, + isValueReference: false, + isWrite: false, + resolved: Variable$7, + }, + ], + isValueVariable: false, + isTypeVariable: true, + }, + Variable$8 { + defs: Array [ + VariableDefinition$6 { + name: Identifier<"makeStringBox">, + node: VariableDeclarator$5, + }, + ], + name: "makeStringBox", + references: Array [ + Reference$5 { + identifier: Identifier<"makeStringBox">, + init: true, + isRead: false, + isTypeReference: false, + isValueReference: true, + isWrite: true, + resolved: Variable$8, + writeExpr: TSInstantiationExpression$6, + }, + ], + isValueVariable: true, + isTypeVariable: false, + }, + ], + scopes: Array [ + GlobalScope$1 { + block: Program$7, + isStrict: false, + references: Array [ + Reference$5, + Reference$6, + ], + set: Map { + "const" => ImplicitGlobalConstTypeVariable, + "makeBox" => Variable$2, + "BoxFunc" => Variable$6, + "makeStringBox" => Variable$8, + }, + type: "global", + upper: null, + variables: Array [ + ImplicitGlobalConstTypeVariable, + Variable$2, + Variable$6, + Variable$8, + ], + }, + FunctionScope$2 { + block: FunctionDeclaration$1, + isStrict: false, + references: Array [ + Reference$1, + Reference$2, + ], + set: Map { + "arguments" => Variable$3, + "value" => Variable$4, + "T" => Variable$5, + }, + type: "function", + upper: GlobalScope$1, + variables: Array [ + Variable$3, + Variable$4, + Variable$5, + ], + }, + TypeScope$3 { + block: TSTypeAliasDeclaration$3, + isStrict: true, + references: Array [ + Reference$3, + Reference$4, + ], + set: Map { + "T" => Variable$7, + }, + type: "type", + upper: GlobalScope$1, + variables: Array [ + Variable$7, + ], + }, + ], +} +`; diff --git a/packages/shared-fixtures/CHANGELOG.md b/packages/shared-fixtures/CHANGELOG.md index 4ef0517e5388..9eb4fbd30758 100644 --- a/packages/shared-fixtures/CHANGELOG.md +++ b/packages/shared-fixtures/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.31.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.30.7...v5.31.0) (2022-07-25) + +**Note:** Version bump only for package @typescript-eslint/shared-fixtures + + + + + ## [5.30.7](https://github.com/typescript-eslint/typescript-eslint/compare/v5.30.6...v5.30.7) (2022-07-18) **Note:** Version bump only for package @typescript-eslint/shared-fixtures diff --git a/packages/shared-fixtures/package.json b/packages/shared-fixtures/package.json index b45a8fcf87b9..aaf5ae877894 100644 --- a/packages/shared-fixtures/package.json +++ b/packages/shared-fixtures/package.json @@ -1,5 +1,5 @@ { "name": "@typescript-eslint/shared-fixtures", - "version": "5.30.7", + "version": "5.31.0", "private": true } diff --git a/packages/type-utils/CHANGELOG.md b/packages/type-utils/CHANGELOG.md index 416f0de1c6d0..5fb62320d696 100644 --- a/packages/type-utils/CHANGELOG.md +++ b/packages/type-utils/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.31.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.30.7...v5.31.0) (2022-07-25) + +**Note:** Version bump only for package @typescript-eslint/type-utils + + + + + ## [5.30.7](https://github.com/typescript-eslint/typescript-eslint/compare/v5.30.6...v5.30.7) (2022-07-18) **Note:** Version bump only for package @typescript-eslint/type-utils diff --git a/packages/type-utils/package.json b/packages/type-utils/package.json index d5df5186d471..f459f69c0511 100644 --- a/packages/type-utils/package.json +++ b/packages/type-utils/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/type-utils", - "version": "5.30.7", + "version": "5.31.0", "description": "Type utilities for working with TypeScript + ESLint together", "keywords": [ "eslint", @@ -39,12 +39,12 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/utils": "5.30.7", + "@typescript-eslint/utils": "5.31.0", "debug": "^4.3.4", "tsutils": "^3.21.0" }, "devDependencies": { - "@typescript-eslint/parser": "5.30.7", + "@typescript-eslint/parser": "5.31.0", "typescript": "*" }, "peerDependencies": { diff --git a/packages/types/CHANGELOG.md b/packages/types/CHANGELOG.md index 6e0e5f265b3b..a349101ec1f4 100644 --- a/packages/types/CHANGELOG.md +++ b/packages/types/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.31.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.30.7...v5.31.0) (2022-07-25) + +**Note:** Version bump only for package @typescript-eslint/types + + + + + ## [5.30.7](https://github.com/typescript-eslint/typescript-eslint/compare/v5.30.6...v5.30.7) (2022-07-18) diff --git a/packages/types/package.json b/packages/types/package.json index 68bb90c56667..428f0a747077 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/types", - "version": "5.30.7", + "version": "5.31.0", "description": "Types for the TypeScript-ESTree AST spec", "keywords": [ "eslint", diff --git a/packages/typescript-estree/CHANGELOG.md b/packages/typescript-estree/CHANGELOG.md index 84cd407ccb58..b2dd189b6a49 100644 --- a/packages/typescript-estree/CHANGELOG.md +++ b/packages/typescript-estree/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.31.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.30.7...v5.31.0) (2022-07-25) + +**Note:** Version bump only for package @typescript-eslint/typescript-estree + + + + + ## [5.30.7](https://github.com/typescript-eslint/typescript-eslint/compare/v5.30.6...v5.30.7) (2022-07-18) diff --git a/packages/typescript-estree/package.json b/packages/typescript-estree/package.json index f34ba70d4104..df745ec45e12 100644 --- a/packages/typescript-estree/package.json +++ b/packages/typescript-estree/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/typescript-estree", - "version": "5.30.7", + "version": "5.31.0", "description": "A parser that converts TypeScript source code into an ESTree compatible form", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -42,8 +42,8 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/types": "5.30.7", - "@typescript-eslint/visitor-keys": "5.30.7", + "@typescript-eslint/types": "5.31.0", + "@typescript-eslint/visitor-keys": "5.31.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -59,7 +59,7 @@ "@types/is-glob": "*", "@types/semver": "*", "@types/tmp": "*", - "@typescript-eslint/shared-fixtures": "5.30.7", + "@typescript-eslint/shared-fixtures": "5.31.0", "glob": "*", "jest-specific-snapshot": "*", "make-dir": "*", diff --git a/packages/utils/CHANGELOG.md b/packages/utils/CHANGELOG.md index 611e9976d8cc..daa12050bc34 100644 --- a/packages/utils/CHANGELOG.md +++ b/packages/utils/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.31.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.30.7...v5.31.0) (2022-07-25) + +**Note:** Version bump only for package @typescript-eslint/utils + + + + + ## [5.30.7](https://github.com/typescript-eslint/typescript-eslint/compare/v5.30.6...v5.30.7) (2022-07-18) **Note:** Version bump only for package @typescript-eslint/utils diff --git a/packages/utils/package.json b/packages/utils/package.json index 87605d9fb9d4..c0507bc0e84d 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/utils", - "version": "5.30.7", + "version": "5.31.0", "description": "Utilities for working with TypeScript + ESLint together", "keywords": [ "eslint", @@ -40,9 +40,9 @@ }, "dependencies": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.30.7", - "@typescript-eslint/types": "5.30.7", - "@typescript-eslint/typescript-estree": "5.30.7", + "@typescript-eslint/scope-manager": "5.31.0", + "@typescript-eslint/types": "5.31.0", + "@typescript-eslint/typescript-estree": "5.31.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" }, diff --git a/packages/visitor-keys/CHANGELOG.md b/packages/visitor-keys/CHANGELOG.md index a2e4aefcab0c..6cbcb6b7a475 100644 --- a/packages/visitor-keys/CHANGELOG.md +++ b/packages/visitor-keys/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.31.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.30.7...v5.31.0) (2022-07-25) + +**Note:** Version bump only for package @typescript-eslint/visitor-keys + + + + + ## [5.30.7](https://github.com/typescript-eslint/typescript-eslint/compare/v5.30.6...v5.30.7) (2022-07-18) diff --git a/packages/visitor-keys/package.json b/packages/visitor-keys/package.json index f42d7bd6696e..eccaeefe1f20 100644 --- a/packages/visitor-keys/package.json +++ b/packages/visitor-keys/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/visitor-keys", - "version": "5.30.7", + "version": "5.31.0", "description": "Visitor keys used to help traverse the TypeScript-ESTree AST", "keywords": [ "eslint", @@ -39,7 +39,7 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/types": "5.30.7", + "@typescript-eslint/types": "5.31.0", "eslint-visitor-keys": "^3.3.0" }, "devDependencies": { diff --git a/packages/website-eslint/CHANGELOG.md b/packages/website-eslint/CHANGELOG.md index e91cc703744d..637e723e221d 100644 --- a/packages/website-eslint/CHANGELOG.md +++ b/packages/website-eslint/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.31.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.30.7...v5.31.0) (2022-07-25) + +**Note:** Version bump only for package @typescript-eslint/website-eslint + + + + + ## [5.30.7](https://github.com/typescript-eslint/typescript-eslint/compare/v5.30.6...v5.30.7) (2022-07-18) **Note:** Version bump only for package @typescript-eslint/website-eslint diff --git a/packages/website-eslint/package.json b/packages/website-eslint/package.json index 7ced00a1b625..28493ffc35ac 100644 --- a/packages/website-eslint/package.json +++ b/packages/website-eslint/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/website-eslint", - "version": "5.30.7", + "version": "5.31.0", "private": true, "description": "ESLint which works in browsers.", "engines": { @@ -16,19 +16,19 @@ "format": "prettier --write \"./**/*.{ts,mts,cts,tsx,js,mjs,cjs,jsx,json,md,css}\" --ignore-path ../../.prettierignore" }, "dependencies": { - "@typescript-eslint/types": "5.30.7", - "@typescript-eslint/utils": "5.30.7" + "@typescript-eslint/types": "5.31.0", + "@typescript-eslint/utils": "5.31.0" }, "devDependencies": { "@rollup/plugin-commonjs": "^22.0.0", "@rollup/plugin-json": "^4.1.0", "@rollup/plugin-node-resolve": "^13.3.0", "@rollup/pluginutils": "^4.2.1", - "@typescript-eslint/eslint-plugin": "5.30.7", - "@typescript-eslint/parser": "5.30.7", - "@typescript-eslint/scope-manager": "5.30.7", - "@typescript-eslint/typescript-estree": "5.30.7", - "@typescript-eslint/visitor-keys": "5.30.7", + "@typescript-eslint/eslint-plugin": "5.31.0", + "@typescript-eslint/parser": "5.31.0", + "@typescript-eslint/scope-manager": "5.31.0", + "@typescript-eslint/typescript-estree": "5.31.0", + "@typescript-eslint/visitor-keys": "5.31.0", "eslint": "*", "rollup": "^2.75.4", "rollup-plugin-terser": "^7.0.2", diff --git a/packages/website/CHANGELOG.md b/packages/website/CHANGELOG.md index f144e9ed4acf..f7a084c3dbeb 100644 --- a/packages/website/CHANGELOG.md +++ b/packages/website/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.31.0](https://github.com/typescript-eslint/typescript-eslint/compare/v5.30.7...v5.31.0) (2022-07-25) + +**Note:** Version bump only for package website + + + + + ## [5.30.7](https://github.com/typescript-eslint/typescript-eslint/compare/v5.30.6...v5.30.7) (2022-07-18) **Note:** Version bump only for package website diff --git a/packages/website/docusaurusConfig.ts b/packages/website/docusaurusConfig.ts index ac050430f533..89a97f1c81e7 100644 --- a/packages/website/docusaurusConfig.ts +++ b/packages/website/docusaurusConfig.ts @@ -8,7 +8,7 @@ import type { Config } from '@docusaurus/types'; import { rulesMeta } from './rulesMeta'; import npm2yarnPlugin from '@docusaurus/remark-plugin-npm2yarn'; import tabsPlugin from 'remark-docusaurus-tabs'; -import { addRuleAttributesList } from './plugins/add-rule-attributes-list'; +import { generatedRuleDocs } from './plugins/generated-rule-docs'; const remarkPlugins: MDXPlugin[] = [[npm2yarnPlugin, { sync: true }]]; @@ -24,7 +24,7 @@ const presetClassicOptions: PresetClassicOptions = { routeBasePath: 'rules', editUrl: `${githubUrl}/edit/main/packages/website/`, beforeDefaultRemarkPlugins, - remarkPlugins: [...remarkPlugins, [addRuleAttributesList, {}]], + remarkPlugins: [...remarkPlugins, [generatedRuleDocs, {}]], exclude: ['TEMPLATE.md'], breadcrumbs: false, }, @@ -172,7 +172,7 @@ const config: Config = { url: 'https://typescript-eslint.io', baseUrl: '/', onBrokenLinks: 'throw', - onBrokenMarkdownLinks: 'warn', // If Markdown link resolution fails, it will result in a broken link anyways + onBrokenMarkdownLinks: 'throw', favicon: 'img/favicon.ico', organizationName: 'typescript-eslint', projectName: 'typescript-eslint', diff --git a/packages/website/package.json b/packages/website/package.json index e1279661a079..ee5a05772d95 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -1,6 +1,6 @@ { "name": "website", - "version": "5.30.7", + "version": "5.31.0", "private": true, "scripts": { "build": "docusaurus build", @@ -20,7 +20,7 @@ "@docusaurus/remark-plugin-npm2yarn": "2.0.0-beta.21", "@docusaurus/theme-common": "2.0.0-beta.21", "@mdx-js/react": "1.6.22", - "@typescript-eslint/website-eslint": "5.30.7", + "@typescript-eslint/website-eslint": "5.31.0", "clsx": "^1.1.1", "eslint": "*", "json5": "^2.2.1", @@ -37,7 +37,7 @@ "@types/react": "^18.0.9", "@types/react-helmet": "^6.1.5", "@types/react-router-dom": "^5.3.3", - "@typescript-eslint/eslint-plugin": "5.30.7", + "@typescript-eslint/eslint-plugin": "5.31.0", "copy-webpack-plugin": "^11.0.0", "cypress": "8.3.0", "cypress-axe": "^0.14.0", diff --git a/packages/website/plugins/add-rule-attributes-list.ts b/packages/website/plugins/add-rule-attributes-list.ts deleted file mode 100644 index febbfc355576..000000000000 --- a/packages/website/plugins/add-rule-attributes-list.ts +++ /dev/null @@ -1,38 +0,0 @@ -import type * as unist from 'unist'; -import type * as mdast from 'mdast'; -import type { Plugin } from 'unified'; - -import * as eslintPlugin from '@typescript-eslint/eslint-plugin'; - -const addRuleAttributesList: Plugin = () => { - return (root, file) => { - if (file.stem == null) { - return; - } - - const rule = eslintPlugin.rules[file.stem]; - if (rule == null) { - return; - } - - const parent = root as unist.Parent; - const h2Idx = parent.children.findIndex( - child => child.type === 'heading' && (child as mdast.Heading).depth === 2, - ); - // The actual content will be injected on client side. - const attrNode = { - type: 'jsx', - value: ``, - }; - if (h2Idx != null) { - // insert it just before the first h2 in the doc - // this should be just after the rule's description - parent.children.splice(h2Idx, 0, attrNode); - } else { - // failing that, add it to the end - parent.children.push(attrNode); - } - }; -}; - -export { addRuleAttributesList }; diff --git a/packages/website/plugins/generated-rule-docs.ts b/packages/website/plugins/generated-rule-docs.ts new file mode 100644 index 000000000000..f074db043551 --- /dev/null +++ b/packages/website/plugins/generated-rule-docs.ts @@ -0,0 +1,61 @@ +import type * as unist from 'unist'; +import type * as mdast from 'mdast'; +import type { Plugin } from 'unified'; + +import * as eslintPlugin from '@typescript-eslint/eslint-plugin'; + +const generatedRuleDocs: Plugin = () => { + return (root, file) => { + if (file.stem == null) { + return; + } + + const docs = eslintPlugin.rules[file.stem]?.meta.docs; + if (!docs) { + return; + } + + const parent = root as unist.Parent; + + // 1. Remove the " πŸ›‘ This file is source code, not the primary documentation location! πŸ›‘" + parent.children.splice( + parent.children.findIndex(v => v.type === 'blockquote'), + 1, + ); + + // 2. Add a description of the rule at the top of the file + parent.children.unshift({ + children: [ + { + children: docs.description + .split(/`(.+?)`/) + .map((value, index, array) => ({ + type: index % 2 === 0 ? 'text' : 'inlineCode', + value: index === array.length - 1 ? `${value}.` : value, + })), + type: 'paragraph', + }, + ], + type: 'blockquote', + } as mdast.Blockquote); + + // 3. Add a rule attributes list... + const h2Idx = + // ...before the first h2, if it exists... + parent.children.findIndex( + child => + child.type === 'heading' && (child as mdast.Heading).depth === 2, + ) ?? + // ...or at the very end, if not. + parent.children.length; + + // The actual content will be injected on client side. + const attrNode = { + type: 'jsx', + value: ``, + }; + parent.children.splice(h2Idx, 0, attrNode); + }; +}; + +export { generatedRuleDocs }; diff --git a/packages/website/sidebars/sidebar.base.js b/packages/website/sidebars/sidebar.base.js index 8fbf27e2dc93..5b16af7f5f91 100644 --- a/packages/website/sidebars/sidebar.base.js +++ b/packages/website/sidebars/sidebar.base.js @@ -1,18 +1,37 @@ module.exports = { docs: [ - 'README', { - type: 'category', - label: 'Linting', collapsed: false, items: [ - 'linting/linting', - 'linting/type-linting', + { + label: 'Linting with Type Information', + items: ['linting/typed-linting/monorepos'], + link: { + id: 'linting/typed-linting', + type: 'doc', + }, + type: 'category', + }, 'linting/configs', - 'linting/monorepo', - 'linting/troubleshooting', - 'linting/tslint', + { + label: 'Troubleshooting & FAQs', + link: { + id: 'linting/troubleshooting', + type: 'doc', + }, + type: 'category', + items: [ + 'linting/troubleshooting/formatting', + 'linting/troubleshooting/tslint', + ], + }, ], + link: { + id: 'getting-started', + type: 'doc', + }, + label: 'Getting Started', + type: 'category', }, { type: 'category', diff --git a/packages/website/src/components/OptionsSelector.tsx b/packages/website/src/components/OptionsSelector.tsx index f57f2600f49c..b9b78edfad09 100644 --- a/packages/website/src/components/OptionsSelector.tsx +++ b/packages/website/src/components/OptionsSelector.tsx @@ -90,10 +90,9 @@ function OptionsSelectorContent({ name="ts" className="text--right" value={state.ts} + disabled={!tsVersions.length} onChange={updateTS} - options={((tsVersions.length && tsVersions) || [state.ts]).filter( - item => parseFloat(item) >= 3.3, - )} + options={(tsVersions.length && tsVersions) || [state.ts]} />