From 10075acf3efad2e4a5c84d4a5e1972331321c338 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Wed, 22 Feb 2023 12:01:17 -0500 Subject: [PATCH 01/14] docs: add v6 upgrade blog post --- ...03-07-upgrading-to-typescript-eslint-v6.md | 130 ++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 packages/website/blog/2023-03-07-upgrading-to-typescript-eslint-v6.md diff --git a/packages/website/blog/2023-03-07-upgrading-to-typescript-eslint-v6.md b/packages/website/blog/2023-03-07-upgrading-to-typescript-eslint-v6.md new file mode 100644 index 000000000000..b0667f3c7458 --- /dev/null +++ b/packages/website/blog/2023-03-07-upgrading-to-typescript-eslint-v6.md @@ -0,0 +1,130 @@ +--- +authors: + - image_url: https://www.joshuakgoldberg.com/img/josh.jpg + name: Josh Goldberg + title: typescript-eslint Maintainer + url: https://github.com/JoshuaKGoldberg +description: Describing what an AST (Abstract Syntax Tree) is and why it's useful for ESLint and TypeScript tooling. +slug: upgrading-to-typescript-eslint-v6 +tags: [breaking changes, typescript-eslint, v5, v6] +title: Upgrading to typescript-eslint v6 +--- + +[typescript-eslint](https://typescript-eslint.io) is the tooling that enables standard JavaScript tools such as [ESLint](https://eslint.org) and [Prettier](https://prettier.io) to support TypeScript code. +We've been working on a set of breaking changes and general features that we're excited to get in front of users soon. +typescript-eslint v6 contains over a year's worth of improvements + +## Trying Out v6 + +> Todo: actual setup instructions! + +```shell +npm i @typescript-eslint/eslint-plugin@rc-v6 @typescript-eslint/parser@rc-v6 +``` + +## New Features + +## User-Facing Features + +## User-Facing Features + +## User-Facing Breaking Changes + +### Configuration Breaking Changes + +- [fix(eslint-plugin): remove valid-typeof disable in eslint-recommended](https://github.com/typescript-eslint/typescript-eslint/pull/5381): Removes the disabling of ESLint's `valid-typeof` rule from our preset configs. + +#### [feat(eslint-plugin): rework configs: recommended, strict, stylistic; -type-checked](https://github.com/typescript-eslint/typescript-eslint/pull/5251) + +The biggest configuration change in typescript-eslint v6 is that we've reworked the names of our [provided user configuration files](https://typescript-eslint.io/linting/configs). +typescript-eslint v5 provided three recommended configurations: + +- [`plugin:@typescript-eslint/recommended`](https://typescript-eslint.io/linting/configs#recommended): Recommended rules for code correctness that you can drop in without additional configuration. +- [`plugin:@typescript-eslint/recommended-requiring-type-checking`](https://typescript-eslint.io/linting/configs#recommended-requiring-type-checking): Additional recommended rules that require type information. +- [`plugin:@typescript-eslint/strict`](https://typescript-eslint.io/linting/configs#strict): Additional strict rules that can also catch bugs but are more opinionated than recommended rules. + +Those configurations worked well for most projects. +However, some users correctly noted two flaws in that approach: + +- Strict rules that didn't require type checking were lumped in with those that did. +- _Stylistic_ best practices were lumped in with rules that actually find bugs. + +As a result, we've reworked the configurations provided by typescript-eslint into the two sections: + +- Functional rule configurations, for best best practices and code correctness: + - `plugin:@typescript-eslint/recommended`: Recommended rules that you can drop in without additional configuration. + - `plugin:@typescript-eslint/recommended-type-checked`: Additional recommended rules that require type information. + - `plugin:@typescript-eslint/strict`: Additional strict rules that can also catch bugs but are more opinionated than recommended rules _(without type information)_. + - `plugin:@typescript-eslint/strict-type-checked`: Additional strict rules that do require type information. +- Stylistic rule configurations, for consistent and predictable syntax usage: + - `plugin:@typescript-eslint/stylistic`: Stylistic rules you can drop in without additional configuration. + - `plugin:@typescript-eslint/stylistic-type-checked`: Additional stylistic rules that require type information. + +> `plugin:@typescript-eslint/recommended-requiring-type-checking` is now an alias for `plugin:@typescript-eslint/recommended-type-checked`. +> The alias will be removed in a future major version. + +As of v6, we recommend that projects enable two configs from the above: + +- If you are _not_ using typed linting, enable `stylistic` and either `recommended` or `strict`, depending on how intensely you'd like your lint rules to scrutinize your code. +- If you _are_ using typed linting, enable `stylistic-type-checked` and either `recommended-type-checked` or `strict-type-checked`, depending on how intensely you'd like your lint rules to scrutinize your code. + +See [Configs: Have recommended/strict configs include lesser configs, and simplify type checked names](https://github.com/typescript-eslint/typescript-eslint/discussions/6019) for the discussion leading up to these configuration changes. + +#### Updated Configurations List + +See [](https://github.com/typescript-eslint/typescript-eslint/discussions/6014) for + +### Rule Breaking Changes + +- [feat(eslint-plugin): deprecate no-type-alias](https://github.com/typescript-eslint/typescript-eslint/pull/6229): Deprecates [`@typescript-eslint/no-type-alias`](https://typescript-eslint.io/rules/no-this-alias), as it does not enforce any best practices we recommend. +- [feat(eslint-plugin): [prefer-nullish-coalescing]: add support for assignment expressions](https://github.com/typescript-eslint/typescript-eslint/pull/5234): Enhances the [`@typescript-eslint/prefer-nullish-coalescing`](https://typescript-eslint.io/prefer-nullish-coalescing) rule to also check `||=` expressions. + +### Tooling Breaking Changes + +- [feat(typescript-estree): deprecate createDefaultProgram](https://github.com/typescript-eslint/typescript-eslint/pull/5890): Renames `createDefaultProgram` to `deprecated__createDefaultProgram`, with associated `@deprecated` TSDoc tags and warnings. +- [feat: drop support for node v12](https://github.com/typescript-eslint/typescript-eslint/pull/5918) +- [feat: bump minimum supported TS version to 4.2.4](https://github.com/typescript-eslint/typescript-eslint/pull/5915) +- [chore: drop support for ESLint v6](https://github.com/typescript-eslint/typescript-eslint/pull/5972) + +## Developer-Facing Breaking Changes + +typescript-eslint v6 comes with a suite of cleanups and improvements for developers as well. +If you author any ESLint plugins or other tools that interact with TypeScript syntax, then we recommend you try out typescript-eslint v6 soon. +It includes some breaking changes that you may need to accommodate for. + +:::tip +If you're having trouble working with the changes, please let us know! +::: + +### AST Breaking Changes + +These PRs changed the AST shapes generated by typescript-eslint when parsing code. +If you author any ESLint rules that refer to the syntax mentioned by them, these are relevant to you. + +- [feat: made BaseNode.parent non-optional](https://github.com/typescript-eslint/typescript-eslint/pull/5252): makes the `node.parent` property on AST nodes non-optional (`TSESTree.Node` instead of `TSESTree.Node | undefined`). +- [fix(ast-spec): correct some incorrect ast types](https://github.com/typescript-eslint/typescript-eslint/pull/6257): applies the following changes to correct erroneous types of AST node properties: + - `ArrayExpressions`'s `elements` property can now include `null` (i.e. is now `(Expression | SpreadElement | null)[]`), for the case of sparse arrays (e.g. `[1, , 3]`). + - `MemberExpression`'s `object` property is now `Expression`, not `LeftHandSideExpression`. + - `ObjectLiteralElement` no longer allows for `MethodDefinition`. +- [fix(typescript-estree): wrap import = declaration in an export node](https://github.com/typescript-eslint/typescript-eslint/pull/5885): Exported `TSImportEqualsDeclaration` nodes are now wrapped in an `ExportNamedDeclaration` node instead of having `.isExport = true` property. +- [fix(ast-spec): remove more invalid properties](https://github.com/typescript-eslint/typescript-eslint/pull/6243): applies the following changes to remove invalid properties from AST nodes: + - `MethodDefinitionBase` no longer has a `typeParameters` property. + - `TSIndexSignature`, `TSMethodSignature`, and `TSPropertySignatureBase` no longer have an `export` property. + - `TSPropertySignatureBase` no longer has an `initializer` property. +- [fix(typescript-estree): account for namespace nesting in AST conversion](https://github.com/typescript-eslint/typescript-eslint/pull/6272): Namespaces with qualified names like `Abc.Def` now use a `TSQualifiedName` node, instead of a nested body structure. + +### Other Developer-Facing Breaking Changes + +- [feat: remove semantically invalid properties from TSEnumDeclaration, TSInterfaceDeclaration and TSModuleDeclaration](https://github.com/typescript-eslint/typescript-eslint/pull/4863): Removes some properties from those AST node types that should generally not have existed to begin with. +- [fix(utils): removed TRuleListener generic from the createRule](https://github.com/typescript-eslint/typescript-eslint/pull/5036): Makes `createRule`-created rules more portable in the type system. +- [feat(utils): remove (ts-)eslint-scope types](https://github.com/typescript-eslint/typescript-eslint/pull/5256): Removes no-longer-useful `TSESLintScope` types from the `@typescript-eslint/utils` package. +- [feat(scope-manager): ignore ECMA version](https://github.com/typescript-eslint/typescript-eslint/pull/5889): `@typescript-eslint/scope-manager` no longer includes properties referring to `ecmaVersion`, `isES6`, or other ECMA versioning options. It instead now always assumes ESNext. +- [feat(experimental-utils): console.warn on import of experimental-utils](https://github.com/typescript-eslint/typescript-eslint/pull/6179): The `@typescript-eslint/experimental-utils` package has since been renamed to `@typescript-eslint/utils`. The old package name now includes a `console.warn` message to indicate you should switch to the new package name. +- [feat: remove partial type-information program](https://github.com/typescript-eslint/typescript-eslint/pull/6066): When user configurations don't provide a `parserOptions.project`, parser services will no longer include a `program` with incomplete type information. `program` will be `null` instead. + - As a result, the `errorOnTypeScriptSyntacticAndSemanticIssues` option will no longer be allowed if `parserOptions.project` is not provided. +- [chore(typescript-estree): remove visitor-keys backwards compat export](https://github.com/typescript-eslint/typescript-eslint/pull/6242): `visitorKeys` can now only be imported from `@typescript-eslint/visitor-keys`. Previously it was also re-exported by `@typescript-eslint/utils`. +- [feat: add package.json exports for public packages](https://github.com/typescript-eslint/typescript-eslint/pull/6458): `@typescript-eslint/*` packages now use `exports` to prevent importing internal file paths. + +## Other Changes + +## TODO: We'll thank everyone who contributed :) From 2c88a0b17d9d33251121fb5b41f69fd40ecf3881 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Wed, 22 Feb 2023 12:23:51 -0500 Subject: [PATCH 02/14] Mention project: true --- ...03-07-upgrading-to-typescript-eslint-v6.md | 54 +++++++++++++++++-- 1 file changed, 49 insertions(+), 5 deletions(-) diff --git a/packages/website/blog/2023-03-07-upgrading-to-typescript-eslint-v6.md b/packages/website/blog/2023-03-07-upgrading-to-typescript-eslint-v6.md index b0667f3c7458..5224b438df8d 100644 --- a/packages/website/blog/2023-03-07-upgrading-to-typescript-eslint-v6.md +++ b/packages/website/blog/2023-03-07-upgrading-to-typescript-eslint-v6.md @@ -22,11 +22,47 @@ typescript-eslint v6 contains over a year's worth of improvements npm i @typescript-eslint/eslint-plugin@rc-v6 @typescript-eslint/parser@rc-v6 ``` -## New Features - ## User-Facing Features -## User-Facing Features +### Relative `tsconfig.json` Projects + +In typescript-eslint v5, in order to enable [typed linting](https://typescript-eslint.io/linting/typed-linting), your ESLint configuration must include a `parserOptions.project` property indicating which TSConfig(s) to use: + +```js title=".eslintrc.cjs" +module.exports = { + // ... + parserOptions: { + project: ['./tsconfig.json'], + }, + // ... +}; +``` + +This works well for repositories that have a single TSConfig for all files, such as small repositories using a single `tsconfig.json` or larger monorepos that have a `tsconfig.eslint.json` specifically used for linting. +But what if your project uses different TSConfig options for different TypeScript files in nested subdirectories? + +... + +We recently added the option to specify `parserOptions.project` as just `true` in ESLint configurations. +This indicates to typescript-eslint that each file should be linted with the closest `tsconfig.json` file on disk. + +```js title=".eslintrc.cjs" +module.exports = { + // ... + parserOptions: { + project: true, + }, + // ... +}; +``` + +We hope using `project = true` simplifies configurations for repositories with nontrivial ESLint configuration setups. +We intend to add additional options around automatic TSConfig lookups to allow additional file names or other convenient behaviors. + +:::note +`parserOptions.project = true` is available in the latest versions of typescript-eslint v5. +But v6's internal refactors are big enough that we'd like users to also try this out too. +::: ## User-Facing Breaking Changes @@ -72,7 +108,15 @@ See [Configs: Have recommended/strict configs include lesser configs, and simpli #### Updated Configurations List -See [](https://github.com/typescript-eslint/typescript-eslint/discussions/6014) for +Every new major version of typescript-eslint comes with changes to which rules are enabled in the preset configurations - and with which options. +Because this release also includes a reworking of the configurations themselves, the list of changes is too large to put in this blog post. +Instead see [Changes to configurations for 6.0.0](https://github.com/typescript-eslint/typescript-eslint/discussions/6014) for a full list of the changes. + +Please do try out the new rule configurations presets and let us know in that discussion! + +:::tip +todo: give tip on how to clear user config rules before trying out +::: ### Rule Breaking Changes @@ -125,6 +169,6 @@ If you author any ESLint rules that refer to the syntax mentioned by them, these - [chore(typescript-estree): remove visitor-keys backwards compat export](https://github.com/typescript-eslint/typescript-eslint/pull/6242): `visitorKeys` can now only be imported from `@typescript-eslint/visitor-keys`. Previously it was also re-exported by `@typescript-eslint/utils`. - [feat: add package.json exports for public packages](https://github.com/typescript-eslint/typescript-eslint/pull/6458): `@typescript-eslint/*` packages now use `exports` to prevent importing internal file paths. -## Other Changes +## Developer-Facing Features ## TODO: We'll thank everyone who contributed :) From cf1c97763855d005fcf820c03d6892db72d9f4b4 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Wed, 22 Feb 2023 12:37:58 -0500 Subject: [PATCH 03/14] Mention TS wrapping APIs too --- ...03-07-upgrading-to-typescript-eslint-v6.md | 61 ++++++++++++++++++- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/packages/website/blog/2023-03-07-upgrading-to-typescript-eslint-v6.md b/packages/website/blog/2023-03-07-upgrading-to-typescript-eslint-v6.md index 5224b438df8d..25ddb96c2d80 100644 --- a/packages/website/blog/2023-03-07-upgrading-to-typescript-eslint-v6.md +++ b/packages/website/blog/2023-03-07-upgrading-to-typescript-eslint-v6.md @@ -40,8 +40,7 @@ module.exports = { This works well for repositories that have a single TSConfig for all files, such as small repositories using a single `tsconfig.json` or larger monorepos that have a `tsconfig.eslint.json` specifically used for linting. But what if your project uses different TSConfig options for different TypeScript files in nested subdirectories? - -... +Specifying the right array of relative TSConfig paths to try for each file in order can be cumbersome or downright impossible. We recently added the option to specify `parserOptions.project` as just `true` in ESLint configurations. This indicates to typescript-eslint that each file should be linted with the closest `tsconfig.json` file on disk. @@ -64,6 +63,64 @@ We intend to add additional options around automatic TSConfig lookups to allow a But v6's internal refactors are big enough that we'd like users to also try this out too. ::: +## Developer-Facing Features + +:::note +If you don't work on ESLint plugins or with custom ESLint rules, you can skip this section and go straight to _[User-Facing Breaking Changes](#user-facing-breaking-changes)_. +::: + +### Type Checker Wrapper APIs + +As described in our [ASTs and typescript-eslint](/blog/asts-and-typescript-eslint) post, ESLint rules don't natively work with AST nodes compatible with TypeScript's API. +Retrieving type information for an ESLint AST node in a custom rule requires code somewhat like: + +```ts title="custom-rule-with-v5.ts" +{ + // ... + create() { + const services = util.getParserServices(context); + const checker = services.program.getTypeChecker(); + const tsNode = services.esTreeNodeToTSNodeMap.get(esNode); + const type = checker.getTypeAtLocation(node); + + // ... + } + // ... +} +``` + +How cumbersome, just to call to a single method (`getTypeAtLocation`) on the TypeScript API! + +In typescript-eslint v6, we've added a set of wrapper APIs on the `services: ParserServices` object that act as shortcuts for commonly used TypeScript APIs including `getTypeAtLocation`: + +```ts title="custom-rule-with-v6.ts" +{ + // ... + create() { + const services = util.getParserServices(context); + const type = services.getTypeAtLocation(node); + + // ... + } + // ... +} +``` + +For now, the available wrapper APIs are: + +- `getSymbolAtLocation`: directly passes an ESTree node to TypeScript's `checker.getSymbolAtLocation` +- `getTypeAtLocation`: directly passes an ESTree node to TypeScript's `checker.getTypeAtLocation` + +We hope these wrapper APIs make it more convenient to write lint rules that rely on the awesome power of TypeScript's type checking. +In the future, we may add more wrapper APIs, and may even add internal caching to those APIs to improve performance. + +:::note +Rules can still retrieve their full backing TypeScript type checker with `services.program.getTypeChecker()`. +This can be necessary for TypeScript APIs not wrapped by the parser services. +::: + +TODO: set up a v6 netlify deployment so we can link to the docs there! + ## User-Facing Breaking Changes ### Configuration Breaking Changes From c2950dc67724133095b5cc6a2138a760d9ba692f Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Wed, 22 Feb 2023 18:54:43 -0500 Subject: [PATCH 04/14] WIP setup --- ...7-announcing-typescript-eslint-v6-beta.md} | 29 +++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) rename packages/website/blog/{2023-03-07-upgrading-to-typescript-eslint-v6.md => 2023-03-07-announcing-typescript-eslint-v6-beta.md} (90%) diff --git a/packages/website/blog/2023-03-07-upgrading-to-typescript-eslint-v6.md b/packages/website/blog/2023-03-07-announcing-typescript-eslint-v6-beta.md similarity index 90% rename from packages/website/blog/2023-03-07-upgrading-to-typescript-eslint-v6.md rename to packages/website/blog/2023-03-07-announcing-typescript-eslint-v6-beta.md index 25ddb96c2d80..c94f0592debb 100644 --- a/packages/website/blog/2023-03-07-upgrading-to-typescript-eslint-v6.md +++ b/packages/website/blog/2023-03-07-announcing-typescript-eslint-v6-beta.md @@ -5,23 +5,42 @@ authors: title: typescript-eslint Maintainer url: https://github.com/JoshuaKGoldberg description: Describing what an AST (Abstract Syntax Tree) is and why it's useful for ESLint and TypeScript tooling. -slug: upgrading-to-typescript-eslint-v6 +slug: announcing-typescript-eslint-v6-beta tags: [breaking changes, typescript-eslint, v5, v6] -title: Upgrading to typescript-eslint v6 +title: Announcing typescript-eslint v6 Beta --- [typescript-eslint](https://typescript-eslint.io) is the tooling that enables standard JavaScript tools such as [ESLint](https://eslint.org) and [Prettier](https://prettier.io) to support TypeScript code. We've been working on a set of breaking changes and general features that we're excited to get in front of users soon. -typescript-eslint v6 contains over a year's worth of improvements +And now, after over two years of development, we're excited to say that typescript-eslint v6 is ready for public beta testing! 🎉 + +Our plan for typescript-eslint v6 is to: + +1. Have users try out betas starting in early March of 2023 +2. Respond to user feedback for the next 1-3 months +3. Release a stable version summer of 2023 + +Nothing mentioned in this blog post is set in stone. +If you feel passionately about any of the choices we've made here -positively or negatively- then do let us know on [the typescript-eslint Discord](https://hi.joshuakgoldberg.com)! + + ## Trying Out v6 -> Todo: actual setup instructions! +Please do try out the typescript-eslint v6 beta! + +If you don't yet use typescript-eslint, you can go through our [configuration steps]() + +First replace your package's previous versions of `@typescript-eslint/eslint-plugin` and `@typescript-eslint/parser` with `@rc-v6` versions: ```shell -npm i @typescript-eslint/eslint-plugin@rc-v6 @typescript-eslint/parser@rc-v6 +npm i @typescript-eslint/eslint-plugin@rc-v6 @typescript-eslint/parser@rc-v6 --save-dev ``` +We highly recommend then basing your ESLint configuration on the reworked typescript-eslint recommended configurations mentioned [later in this post](#configuration-breaking-changes 'reworked typescript-eslint recommended configurations mentioned later in this post') — especially if it's been a while since you've reworked your linter config. + +At this point, you should be seeing ESLint reports however you'd previously + ## User-Facing Features ### Relative `tsconfig.json` Projects From 2cac2896797cb0cfc07db7210a34b47ff1815832 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Wed, 22 Feb 2023 23:53:42 -0500 Subject: [PATCH 05/14] Generally cleaned up the blog post --- README.md | 5 + ...07-announcing-typescript-eslint-v6-beta.md | 246 +++++++++--------- 2 files changed, 132 insertions(+), 119 deletions(-) diff --git a/README.md b/README.md index 5241dbda4a26..fd3e232b0b7f 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,11 @@

+ + See v6--typescript-eslint.netlify.app for documentation on upcoming v6 release. + +

+

👆

diff --git a/packages/website/blog/2023-03-07-announcing-typescript-eslint-v6-beta.md b/packages/website/blog/2023-03-07-announcing-typescript-eslint-v6-beta.md index c94f0592debb..21ad4efd3716 100644 --- a/packages/website/blog/2023-03-07-announcing-typescript-eslint-v6-beta.md +++ b/packages/website/blog/2023-03-07-announcing-typescript-eslint-v6-beta.md @@ -28,125 +28,28 @@ If you feel passionately about any of the choices we've made here -positively or ## Trying Out v6 Please do try out the typescript-eslint v6 beta! +Its documentation site is hosted on a preview deploy link: **[v6--typescript-eslint.netlify.app](https://v6--typescript-eslint.netlify.app)**. -If you don't yet use typescript-eslint, you can go through our [configuration steps]() +### As A New User -First replace your package's previous versions of `@typescript-eslint/eslint-plugin` and `@typescript-eslint/parser` with `@rc-v6` versions: +If you don't yet use typescript-eslint, you can go through our [configuration steps on the v6 _Getting Started_ docs](https://v6--typescript-eslint.netlify.app/getting-started). +It'll walk you through setting up typescript-eslint in a project. -```shell -npm i @typescript-eslint/eslint-plugin@rc-v6 @typescript-eslint/parser@rc-v6 --save-dev -``` - -We highly recommend then basing your ESLint configuration on the reworked typescript-eslint recommended configurations mentioned [later in this post](#configuration-breaking-changes 'reworked typescript-eslint recommended configurations mentioned later in this post') — especially if it's been a while since you've reworked your linter config. - -At this point, you should be seeing ESLint reports however you'd previously - -## User-Facing Features - -### Relative `tsconfig.json` Projects - -In typescript-eslint v5, in order to enable [typed linting](https://typescript-eslint.io/linting/typed-linting), your ESLint configuration must include a `parserOptions.project` property indicating which TSConfig(s) to use: - -```js title=".eslintrc.cjs" -module.exports = { - // ... - parserOptions: { - project: ['./tsconfig.json'], - }, - // ... -}; -``` - -This works well for repositories that have a single TSConfig for all files, such as small repositories using a single `tsconfig.json` or larger monorepos that have a `tsconfig.eslint.json` specifically used for linting. -But what if your project uses different TSConfig options for different TypeScript files in nested subdirectories? -Specifying the right array of relative TSConfig paths to try for each file in order can be cumbersome or downright impossible. - -We recently added the option to specify `parserOptions.project` as just `true` in ESLint configurations. -This indicates to typescript-eslint that each file should be linted with the closest `tsconfig.json` file on disk. - -```js title=".eslintrc.cjs" -module.exports = { - // ... - parserOptions: { - project: true, - }, - // ... -}; -``` - -We hope using `project = true` simplifies configurations for repositories with nontrivial ESLint configuration setups. -We intend to add additional options around automatic TSConfig lookups to allow additional file names or other convenient behaviors. +### As An Existing User -:::note -`parserOptions.project = true` is available in the latest versions of typescript-eslint v5. -But v6's internal refactors are big enough that we'd like users to also try this out too. -::: +If you already use typescript-eslint, you'll need to first replace your package's previous versions of `@typescript-eslint/eslint-plugin` and `@typescript-eslint/parser` with `@rc-v6` versions: -## Developer-Facing Features - -:::note -If you don't work on ESLint plugins or with custom ESLint rules, you can skip this section and go straight to _[User-Facing Breaking Changes](#user-facing-breaking-changes)_. -::: - -### Type Checker Wrapper APIs - -As described in our [ASTs and typescript-eslint](/blog/asts-and-typescript-eslint) post, ESLint rules don't natively work with AST nodes compatible with TypeScript's API. -Retrieving type information for an ESLint AST node in a custom rule requires code somewhat like: - -```ts title="custom-rule-with-v5.ts" -{ - // ... - create() { - const services = util.getParserServices(context); - const checker = services.program.getTypeChecker(); - const tsNode = services.esTreeNodeToTSNodeMap.get(esNode); - const type = checker.getTypeAtLocation(node); - - // ... - } - // ... -} -``` - -How cumbersome, just to call to a single method (`getTypeAtLocation`) on the TypeScript API! - -In typescript-eslint v6, we've added a set of wrapper APIs on the `services: ParserServices` object that act as shortcuts for commonly used TypeScript APIs including `getTypeAtLocation`: - -```ts title="custom-rule-with-v6.ts" -{ - // ... - create() { - const services = util.getParserServices(context); - const type = services.getTypeAtLocation(node); - - // ... - } - // ... -} +```shell +npm i @typescript-eslint/eslint-plugin@rc-v6 @typescript-eslint/parser@rc-v6 --save-dev ``` -For now, the available wrapper APIs are: - -- `getSymbolAtLocation`: directly passes an ESTree node to TypeScript's `checker.getSymbolAtLocation` -- `getTypeAtLocation`: directly passes an ESTree node to TypeScript's `checker.getTypeAtLocation` - -We hope these wrapper APIs make it more convenient to write lint rules that rely on the awesome power of TypeScript's type checking. -In the future, we may add more wrapper APIs, and may even add internal caching to those APIs to improve performance. - -:::note -Rules can still retrieve their full backing TypeScript type checker with `services.program.getTypeChecker()`. -This can be necessary for TypeScript APIs not wrapped by the parser services. -::: - -TODO: set up a v6 netlify deployment so we can link to the docs there! +We highly recommend then basing your ESLint configuration on the reworked typescript-eslint [recommended configurations mentioned later in this post](#configuration-breaking-changes) — especially if it's been a while since you've reworked your linter config. ## User-Facing Breaking Changes -### Configuration Breaking Changes +These are the changes that users of typescript-eslint -generally, any developer running ESLint on TypeScript code- should pay attention to when upgrading typescript-eslint from v5 to v6. -- [fix(eslint-plugin): remove valid-typeof disable in eslint-recommended](https://github.com/typescript-eslint/typescript-eslint/pull/5381): Removes the disabling of ESLint's `valid-typeof` rule from our preset configs. - -#### [feat(eslint-plugin): rework configs: recommended, strict, stylistic; -type-checked](https://github.com/typescript-eslint/typescript-eslint/pull/5251) +### Reworked Configuration Names The biggest configuration change in typescript-eslint v6 is that we've reworked the names of our [provided user configuration files](https://typescript-eslint.io/linting/configs). typescript-eslint v5 provided three recommended configurations: @@ -164,13 +67,13 @@ However, some users correctly noted two flaws in that approach: As a result, we've reworked the configurations provided by typescript-eslint into the two sections: - Functional rule configurations, for best best practices and code correctness: - - `plugin:@typescript-eslint/recommended`: Recommended rules that you can drop in without additional configuration. - - `plugin:@typescript-eslint/recommended-type-checked`: Additional recommended rules that require type information. - - `plugin:@typescript-eslint/strict`: Additional strict rules that can also catch bugs but are more opinionated than recommended rules _(without type information)_. - - `plugin:@typescript-eslint/strict-type-checked`: Additional strict rules that do require type information. + - **`plugin:@typescript-eslint/recommended`**: Recommended rules that you can drop in without additional configuration. + - **`plugin:@typescript-eslint/recommended-type-checked`**: Additional recommended rules that require type information. + - **`plugin:@typescript-eslint/strict`**: Additional strict rules that can also catch bugs but are more opinionated than recommended rules _(without type information)_. + - **`plugin:@typescript-eslint/strict-type-checked`**: Additional strict rules that do require type information. - Stylistic rule configurations, for consistent and predictable syntax usage: - - `plugin:@typescript-eslint/stylistic`: Stylistic rules you can drop in without additional configuration. - - `plugin:@typescript-eslint/stylistic-type-checked`: Additional stylistic rules that require type information. + - **`plugin:@typescript-eslint/stylistic`**: Stylistic rules you can drop in without additional configuration. + - **`plugin:@typescript-eslint/stylistic-type-checked`**: Additional stylistic rules that require type information. > `plugin:@typescript-eslint/recommended-requiring-type-checking` is now an alias for `plugin:@typescript-eslint/recommended-type-checked`. > The alias will be removed in a future major version. @@ -180,20 +83,55 @@ As of v6, we recommend that projects enable two configs from the above: - If you are _not_ using typed linting, enable `stylistic` and either `recommended` or `strict`, depending on how intensely you'd like your lint rules to scrutinize your code. - If you _are_ using typed linting, enable `stylistic-type-checked` and either `recommended-type-checked` or `strict-type-checked`, depending on how intensely you'd like your lint rules to scrutinize your code. -See [Configs: Have recommended/strict configs include lesser configs, and simplify type checked names](https://github.com/typescript-eslint/typescript-eslint/discussions/6019) for the discussion leading up to these configuration changes. +For example, a typical project that enables typed linting might have an ESLint configuration file like: -#### Updated Configurations List +```js title=".eslintrc.cjs" +module.exports = { + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended-type-checked', + 'plugin:@typescript-eslint/stylistic-type-checked', + ], + plugins: ['@typescript-eslint'], + parser: '@typescript-eslint/parser', + parserOptions: { + project: true, + tsconfigRootDir: __dirname, + }, + root: true, +}; +``` + +See [_Configurations_ on the v6 docs site preview](https://v6--typescript-eslint.netlify.app/linting/configs) for the updated documentation on configurations provided by typescript-eslint. + +For more information on these changes, see: + +- [Configs: Have recommended/strict configs include lesser configs, and simplify type checked names](https://github.com/typescript-eslint/typescript-eslint/discussions/6019) for the discussion leading up to these configuration changes. +- [feat(eslint-plugin): rework configs: recommended, strict, stylistic; -type-checked](https://github.com/typescript-eslint/typescript-eslint/pull/5251) for the pull request implementing the changes. + +#### Updated Configuration Rules Every new major version of typescript-eslint comes with changes to which rules are enabled in the preset configurations - and with which options. Because this release also includes a reworking of the configurations themselves, the list of changes is too large to put in this blog post. -Instead see [Changes to configurations for 6.0.0](https://github.com/typescript-eslint/typescript-eslint/discussions/6014) for a full list of the changes. +Instead see the table in [Changes to configurations for 6.0.0](https://github.com/typescript-eslint/typescript-eslint/discussions/6014) for a full list of the changes. Please do try out the new rule configurations presets and let us know in that discussion! :::tip -todo: give tip on how to clear user config rules before trying out +If your ESLint configuration contains many `rules` configurations, we suggest the following strategy to start anew: + +1. Remove all your rules configurations +2. Extend from the preset configs that make sense for you +3. Run ESLint on your project +4. In your ESLint configuration, turn off any rules creating errors that don't make sense for your project - with comments explaining why +5. In your ESLint configuration and/or with inline `eslint-disable` comments, turn off any rules creating too many errors for you to fix - with _"TODO"_ comments linking to tracking issues/tickets to re-enable them + ::: +Miscellaneous changes to all shared configurations include: + +- [fix(eslint-plugin): remove valid-typeof disable in eslint-recommended](https://github.com/typescript-eslint/typescript-eslint/pull/5381): Removes the disabling of ESLint's `valid-typeof` rule from our preset configs. + ### Rule Breaking Changes - [feat(eslint-plugin): deprecate no-type-alias](https://github.com/typescript-eslint/typescript-eslint/pull/6229): Deprecates [`@typescript-eslint/no-type-alias`](https://typescript-eslint.io/rules/no-this-alias), as it does not enforce any best practices we recommend. @@ -247,4 +185,74 @@ If you author any ESLint rules that refer to the syntax mentioned by them, these ## Developer-Facing Features -## TODO: We'll thank everyone who contributed :) +:::note +If you don't work on ESLint plugins or with custom ESLint rules, you can skip this section and go straight to _[User-Facing Breaking Changes](#user-facing-breaking-changes)_. +::: + +### Type Checker Wrapper APIs + +As described in our [ASTs and typescript-eslint](/blog/asts-and-typescript-eslint) post, ESLint rules don't natively work with AST nodes compatible with TypeScript's API. +Retrieving type information for an ESLint AST node in a custom rule requires code somewhat like: + +```ts title="custom-rule-with-v5.ts" +{ + // ... + create() { + const services = util.getParserServices(context); + const checker = services.program.getTypeChecker(); + const tsNode = services.esTreeNodeToTSNodeMap.get(esNode); + const type = checker.getTypeAtLocation(node); + + // ... + } + // ... +} +``` + +How cumbersome, just to call to a single method (`getTypeAtLocation`) on the TypeScript API! + +In typescript-eslint v6, we've added a set of wrapper APIs on the `services: ParserServices` object that act as shortcuts for commonly used TypeScript APIs including `getTypeAtLocation`: + +```ts title="custom-rule-with-v6.ts" +{ + // ... + create() { + const services = util.getParserServices(context); + const type = services.getTypeAtLocation(node); + + // ... + } + // ... +} +``` + +For now, the available wrapper APIs are: + +- `getSymbolAtLocation`: directly passes an ESTree node to TypeScript's `checker.getSymbolAtLocation` +- `getTypeAtLocation`: directly passes an ESTree node to TypeScript's `checker.getTypeAtLocation` + +We hope these wrapper APIs make it more convenient to write lint rules that rely on the awesome power of TypeScript's type checking. +In the future, we may add more wrapper APIs, and may even add internal caching to those APIs to improve performance. + +:::note +Rules can still retrieve their full backing TypeScript type checker with `services.program.getTypeChecker()`. +This can be necessary for TypeScript APIs not wrapped by the parser services. +::: + +See [_Custom Rules_ on the v6 docs site preview](https://v6--typescript-eslint.netlify.app/custom-rules) for the updated documentation on creating custom rules with typescript-eslint. + +## Appreciation + +We'd like to extend a sincere _thank you_ to everybody who pitched in to make typescript-eslint v6 possible. +We couldn't have done it without you! + +See the [v6.0.0 pull request](https://github.com/typescript-eslint/typescript-eslint/pull/5886) for a list of collaborators and merged pull request commits. + +> Beware: there are >400k line changes across >1.5k files. +> The github.com file viewer generally cannot handle viewing the _Files_ tab. + +## Supporting typescript-eslint + +If you enjoyed this blog post and/or or use typescript-eslint, please consider [supporting us on Open Collective](https://opencollective.com/typescript-eslint). +We're a small volunteer team and could use your support to make the ESLint experience on TypeScript great. +Thanks! 💖 From 05f8cf10b28d081e78306671cc3f0cc032e30614 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Thu, 23 Feb 2023 00:02:03 -0500 Subject: [PATCH 06/14] Small organizational cleanups --- .../2023-03-07-announcing-typescript-eslint-v6-beta.md | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/packages/website/blog/2023-03-07-announcing-typescript-eslint-v6-beta.md b/packages/website/blog/2023-03-07-announcing-typescript-eslint-v6-beta.md index 21ad4efd3716..d2754d8587c9 100644 --- a/packages/website/blog/2023-03-07-announcing-typescript-eslint-v6-beta.md +++ b/packages/website/blog/2023-03-07-announcing-typescript-eslint-v6-beta.md @@ -109,7 +109,7 @@ For more information on these changes, see: - [Configs: Have recommended/strict configs include lesser configs, and simplify type checked names](https://github.com/typescript-eslint/typescript-eslint/discussions/6019) for the discussion leading up to these configuration changes. - [feat(eslint-plugin): rework configs: recommended, strict, stylistic; -type-checked](https://github.com/typescript-eslint/typescript-eslint/pull/5251) for the pull request implementing the changes. -#### Updated Configuration Rules +### Updated Configuration Rules Every new major version of typescript-eslint comes with changes to which rules are enabled in the preset configurations - and with which options. Because this release also includes a reworking of the configurations themselves, the list of changes is too large to put in this blog post. @@ -144,7 +144,7 @@ Miscellaneous changes to all shared configurations include: - [feat: bump minimum supported TS version to 4.2.4](https://github.com/typescript-eslint/typescript-eslint/pull/5915) - [chore: drop support for ESLint v6](https://github.com/typescript-eslint/typescript-eslint/pull/5972) -## Developer-Facing Breaking Changes +## Developer-Facing Changes typescript-eslint v6 comes with a suite of cleanups and improvements for developers as well. If you author any ESLint plugins or other tools that interact with TypeScript syntax, then we recommend you try out typescript-eslint v6 soon. @@ -183,12 +183,6 @@ If you author any ESLint rules that refer to the syntax mentioned by them, these - [chore(typescript-estree): remove visitor-keys backwards compat export](https://github.com/typescript-eslint/typescript-eslint/pull/6242): `visitorKeys` can now only be imported from `@typescript-eslint/visitor-keys`. Previously it was also re-exported by `@typescript-eslint/utils`. - [feat: add package.json exports for public packages](https://github.com/typescript-eslint/typescript-eslint/pull/6458): `@typescript-eslint/*` packages now use `exports` to prevent importing internal file paths. -## Developer-Facing Features - -:::note -If you don't work on ESLint plugins or with custom ESLint rules, you can skip this section and go straight to _[User-Facing Breaking Changes](#user-facing-breaking-changes)_. -::: - ### Type Checker Wrapper APIs As described in our [ASTs and typescript-eslint](/blog/asts-and-typescript-eslint) post, ESLint rules don't natively work with AST nodes compatible with TypeScript's API. From a4a3e4a6697470eb6b44eea6b41fdf5fecaa8e56 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Thu, 23 Feb 2023 00:52:40 -0500 Subject: [PATCH 07/14] Added pending changes and more reorders --- ...07-announcing-typescript-eslint-v6-beta.md | 113 +++++++++++++----- 1 file changed, 80 insertions(+), 33 deletions(-) diff --git a/packages/website/blog/2023-03-07-announcing-typescript-eslint-v6-beta.md b/packages/website/blog/2023-03-07-announcing-typescript-eslint-v6-beta.md index d2754d8587c9..126bfe24ee1f 100644 --- a/packages/website/blog/2023-03-07-announcing-typescript-eslint-v6-beta.md +++ b/packages/website/blog/2023-03-07-announcing-typescript-eslint-v6-beta.md @@ -21,7 +21,7 @@ Our plan for typescript-eslint v6 is to: 3. Release a stable version summer of 2023 Nothing mentioned in this blog post is set in stone. -If you feel passionately about any of the choices we've made here -positively or negatively- then do let us know on [the typescript-eslint Discord](https://hi.joshuakgoldberg.com)! +If you feel passionately about any of the choices we've made here -positively or negatively- then do let us know on [the typescript-eslint Discord's `v6` channel](https://hi.joshuakgoldberg.com)! @@ -49,6 +49,9 @@ We highly recommend then basing your ESLint configuration on the reworked typesc These are the changes that users of typescript-eslint -generally, any developer running ESLint on TypeScript code- should pay attention to when upgrading typescript-eslint from v5 to v6. +> ⏳ indicates a change that has been scheduled for v6 but not yet released. +> We'll update this blog post as the corresponding pull requests land. + ### Reworked Configuration Names The biggest configuration change in typescript-eslint v6 is that we've reworked the names of our [provided user configuration files](https://typescript-eslint.io/linting/configs). @@ -134,14 +137,22 @@ Miscellaneous changes to all shared configurations include: ### Rule Breaking Changes -- [feat(eslint-plugin): deprecate no-type-alias](https://github.com/typescript-eslint/typescript-eslint/pull/6229): Deprecates [`@typescript-eslint/no-type-alias`](https://typescript-eslint.io/rules/no-this-alias), as it does not enforce any best practices we recommend. +Several rules were changed in significant enough ways to be considered breaking changes: + +- Previously deprecated rules are deleted ([chore(eslint-plugin): remove deprecated rules for v6](https://github.com/typescript-eslint/typescript-eslint/pull/6112)): + - `@typescript-eslint/no-duplicate-imports` + - `@typescript-eslint/no-implicit-any-catch` + - `@typescript-eslint/no-parameter-properties` + - `@typescript-eslint/sort-type-union-intersection-members` - [feat(eslint-plugin): [prefer-nullish-coalescing]: add support for assignment expressions](https://github.com/typescript-eslint/typescript-eslint/pull/5234): Enhances the [`@typescript-eslint/prefer-nullish-coalescing`](https://typescript-eslint.io/prefer-nullish-coalescing) rule to also check `||=` expressions. +- [fix(eslint-plugin): [prefer-function-type] check for merges with type checking](https://github.com/typescript-eslint/typescript-eslint/pull/6104): Fixes edge case bugs in the [`@typescript-eslint/prefer-function-type`](https://typescript-eslint.io/prefer-function-type) rule around function type merges, at the cost of making it require type information. +- ⏳ [feat(eslint-plugin): [prefer-optional-chain] use type checking for strict falsiness](https://github.com/typescript-eslint/typescript-eslint/pull/6240): Fixes edge case bugs in the [`@typescript-eslint/prefer-optional-chain`](https://typescript-eslint.io/prefer-optional-chain) rule around false positives, at the cost of making it require type information. ### Tooling Breaking Changes - [feat(typescript-estree): deprecate createDefaultProgram](https://github.com/typescript-eslint/typescript-eslint/pull/5890): Renames `createDefaultProgram` to `deprecated__createDefaultProgram`, with associated `@deprecated` TSDoc tags and warnings. - [feat: drop support for node v12](https://github.com/typescript-eslint/typescript-eslint/pull/5918) -- [feat: bump minimum supported TS version to 4.2.4](https://github.com/typescript-eslint/typescript-eslint/pull/5915) +- [feat: bump minimum supported TS version to 4.2.4](https://github.com/typescript-eslint/typescript-eslint/pull/5915): this matches [DefinitelyTyped's 2-year support window](https://github.com/DefinitelyTyped/DefinitelyTyped#support-window). - [chore: drop support for ESLint v6](https://github.com/typescript-eslint/typescript-eslint/pull/5972) ## Developer-Facing Changes @@ -151,38 +162,9 @@ If you author any ESLint plugins or other tools that interact with TypeScript sy It includes some breaking changes that you may need to accommodate for. :::tip -If you're having trouble working with the changes, please let us know! +If you're having trouble working with the changes, please let us know on [the typescript-eslint Discord's `v6` channel](https://hi.joshuakgoldberg.com)! ::: -### AST Breaking Changes - -These PRs changed the AST shapes generated by typescript-eslint when parsing code. -If you author any ESLint rules that refer to the syntax mentioned by them, these are relevant to you. - -- [feat: made BaseNode.parent non-optional](https://github.com/typescript-eslint/typescript-eslint/pull/5252): makes the `node.parent` property on AST nodes non-optional (`TSESTree.Node` instead of `TSESTree.Node | undefined`). -- [fix(ast-spec): correct some incorrect ast types](https://github.com/typescript-eslint/typescript-eslint/pull/6257): applies the following changes to correct erroneous types of AST node properties: - - `ArrayExpressions`'s `elements` property can now include `null` (i.e. is now `(Expression | SpreadElement | null)[]`), for the case of sparse arrays (e.g. `[1, , 3]`). - - `MemberExpression`'s `object` property is now `Expression`, not `LeftHandSideExpression`. - - `ObjectLiteralElement` no longer allows for `MethodDefinition`. -- [fix(typescript-estree): wrap import = declaration in an export node](https://github.com/typescript-eslint/typescript-eslint/pull/5885): Exported `TSImportEqualsDeclaration` nodes are now wrapped in an `ExportNamedDeclaration` node instead of having `.isExport = true` property. -- [fix(ast-spec): remove more invalid properties](https://github.com/typescript-eslint/typescript-eslint/pull/6243): applies the following changes to remove invalid properties from AST nodes: - - `MethodDefinitionBase` no longer has a `typeParameters` property. - - `TSIndexSignature`, `TSMethodSignature`, and `TSPropertySignatureBase` no longer have an `export` property. - - `TSPropertySignatureBase` no longer has an `initializer` property. -- [fix(typescript-estree): account for namespace nesting in AST conversion](https://github.com/typescript-eslint/typescript-eslint/pull/6272): Namespaces with qualified names like `Abc.Def` now use a `TSQualifiedName` node, instead of a nested body structure. - -### Other Developer-Facing Breaking Changes - -- [feat: remove semantically invalid properties from TSEnumDeclaration, TSInterfaceDeclaration and TSModuleDeclaration](https://github.com/typescript-eslint/typescript-eslint/pull/4863): Removes some properties from those AST node types that should generally not have existed to begin with. -- [fix(utils): removed TRuleListener generic from the createRule](https://github.com/typescript-eslint/typescript-eslint/pull/5036): Makes `createRule`-created rules more portable in the type system. -- [feat(utils): remove (ts-)eslint-scope types](https://github.com/typescript-eslint/typescript-eslint/pull/5256): Removes no-longer-useful `TSESLintScope` types from the `@typescript-eslint/utils` package. -- [feat(scope-manager): ignore ECMA version](https://github.com/typescript-eslint/typescript-eslint/pull/5889): `@typescript-eslint/scope-manager` no longer includes properties referring to `ecmaVersion`, `isES6`, or other ECMA versioning options. It instead now always assumes ESNext. -- [feat(experimental-utils): console.warn on import of experimental-utils](https://github.com/typescript-eslint/typescript-eslint/pull/6179): The `@typescript-eslint/experimental-utils` package has since been renamed to `@typescript-eslint/utils`. The old package name now includes a `console.warn` message to indicate you should switch to the new package name. -- [feat: remove partial type-information program](https://github.com/typescript-eslint/typescript-eslint/pull/6066): When user configurations don't provide a `parserOptions.project`, parser services will no longer include a `program` with incomplete type information. `program` will be `null` instead. - - As a result, the `errorOnTypeScriptSyntacticAndSemanticIssues` option will no longer be allowed if `parserOptions.project` is not provided. -- [chore(typescript-estree): remove visitor-keys backwards compat export](https://github.com/typescript-eslint/typescript-eslint/pull/6242): `visitorKeys` can now only be imported from `@typescript-eslint/visitor-keys`. Previously it was also re-exported by `@typescript-eslint/utils`. -- [feat: add package.json exports for public packages](https://github.com/typescript-eslint/typescript-eslint/pull/6458): `@typescript-eslint/*` packages now use `exports` to prevent importing internal file paths. - ### Type Checker Wrapper APIs As described in our [ASTs and typescript-eslint](/blog/asts-and-typescript-eslint) post, ESLint rules don't natively work with AST nodes compatible with TypeScript's API. @@ -235,6 +217,71 @@ This can be necessary for TypeScript APIs not wrapped by the parser services. See [_Custom Rules_ on the v6 docs site preview](https://v6--typescript-eslint.netlify.app/custom-rules) for the updated documentation on creating custom rules with typescript-eslint. +### AST Breaking Changes + +These PRs changed the AST shapes generated by typescript-eslint when parsing code. +If you author any ESLint rules that refer to the syntax mentioned by them, these are relevant to you. + +- [feat: made BaseNode.parent non-optional](https://github.com/typescript-eslint/typescript-eslint/pull/5252): makes the `node.parent` property on AST nodes non-optional (`TSESTree.Node` instead of `TSESTree.Node | undefined`). +- [fix(ast-spec): correct some incorrect ast types](https://github.com/typescript-eslint/typescript-eslint/pull/6257): applies the following changes to correct erroneous types of AST node properties: + - `ArrayExpressions`'s `elements` property can now include `null` (i.e. is now `(Expression | SpreadElement | null)[]`), for the case of sparse arrays (e.g. `[1, , 3]`). + - `MemberExpression`'s `object` property is now `Expression`, not `LeftHandSideExpression`. + - `ObjectLiteralElement` no longer allows for `MethodDefinition`. +- [fix(typescript-estree): wrap import = declaration in an export node](https://github.com/typescript-eslint/typescript-eslint/pull/5885): Exported `TSImportEqualsDeclaration` nodes are now wrapped in an `ExportNamedDeclaration` node instead of having `.isExport = true` property. +- [fix(ast-spec): remove more invalid properties](https://github.com/typescript-eslint/typescript-eslint/pull/6243): applies the following changes to remove invalid properties from AST nodes: + - `MethodDefinitionBase` no longer has a `typeParameters` property. + - `TSIndexSignature`, `TSMethodSignature`, and `TSPropertySignatureBase` no longer have an `export` property. + - `TSPropertySignatureBase` no longer has an `initializer` property. +- [fix(typescript-estree): account for namespace nesting in AST conversion](https://github.com/typescript-eslint/typescript-eslint/pull/6272): Namespaces with qualified names like `Abc.Def` now use a `TSQualifiedName` node, instead of a nested body structure. + +### ⏳ Errors on Invalid AST Parsing + +:::note +These changes only impact API consumers of typescript-eslint that work at parsing level. +If the extent of your API usage is writing custom rules, these changes don't impact you. +::: + +The `@typescript-eslint/typescript-estree` parser is by default very forgiving of invalid ASTs. +If it encounters invalid syntax, it will still attempt create an AST if possible: even if required properties of nodes don't exist. + +For example, this snippet of TypeScript code creates a `ClassDeclaration` whose `id` is `null`: + +```ts +export class {} +``` + +Invalid parsed ASTs can cause problems for downstream tools expecting AST nodes to adhere to the ESTree spec. +ESLint rules in particular tend to crash when given invalid ASTs. + +`@typescript-eslint/typescript-estree` will now throw an error when it encounters a known invalid AST such as the `export class {}` example. +This is generally the correct behavior for most parsing contexts so downstream tools don't have to work with a potentially invalid AST. + +For consumers that don't want the updated behavior of throwing on invalid ASTs, a new `allowInvalidAST` option exists to disable the throwing behavior. +Keep in mind that with it enabled, ASTs produced by typescript-eslint might not match their TSESTree type definitions. + +For more information, see: + +- The backing issue: [Parsing: strictly enforce the produced AST matches the spec and enforce most "error recovery" parsing errors](https://github.com/typescript-eslint/typescript-eslint/issues/1852) +- The implementing pull request: [feat(typescript-estree): added allowInvalidAST option to throw on invalid tokens](https://github.com/typescript-eslint/typescript-eslint/pull/6247) + +### Other Developer-Facing Breaking Changes + +- [feat: remove semantically invalid properties from TSEnumDeclaration, TSInterfaceDeclaration and TSModuleDeclaration](https://github.com/typescript-eslint/typescript-eslint/pull/4863): Removes some properties from those AST node types that should generally not have existed to begin with. +- [fix(utils): removed TRuleListener generic from the createRule](https://github.com/typescript-eslint/typescript-eslint/pull/5036): Makes `createRule`-created rules more portable in the type system. +- [feat(utils): remove (ts-)eslint-scope types](https://github.com/typescript-eslint/typescript-eslint/pull/5256): Removes no-longer-useful `TSESLintScope` types from the `@typescript-eslint/utils` package. +- ⏳ [fix: rename typeParameters to typeArguments where needed](https://github.com/typescript-eslint/typescript-eslint/pull/5384): corrects the names of AST properties that were called _parameters_ instead of _arguments_. + - To recap the terminology: + - An _argument_ is something you provide to a recipient, such as a type provided explicitly to a call expression. + - A _parameter_ is how the recipient receives what you provide, such as a function declaration's generic type parameter. + - ⏳ [Enhancement: Add test-only console warnings to deprecated AST properties](https://github.com/typescript-eslint/typescript-eslint/issues/6469): The properties will include a `console.log` that triggers only in test environments, to encourage developers to move off of them. +- [feat(scope-manager): ignore ECMA version](https://github.com/typescript-eslint/typescript-eslint/pull/5889): `@typescript-eslint/scope-manager` no longer includes properties referring to `ecmaVersion`, `isES6`, or other ECMA versioning options. It instead now always assumes ESNext. +- [feat: remove partial type-information program](https://github.com/typescript-eslint/typescript-eslint/pull/6066): When user configurations don't provide a `parserOptions.project`, parser services will no longer include a `program` with incomplete type information. `program` will be `null` instead. +- [feat(experimental-utils): console.warn on import of experimental-utils](https://github.com/typescript-eslint/typescript-eslint/pull/6179): The `@typescript-eslint/experimental-utils` package has since been renamed to `@typescript-eslint/utils`. The old package name now includes a `console.warn` message to indicate you should switch to the new package name. + - As a result, the `errorOnTypeScriptSyntacticAndSemanticIssues` option will no longer be allowed if `parserOptions.project` is not provided. +- ⏳ [feat(typescript-estree): remove optionality from AST boolean properties](https://github.com/typescript-eslint/typescript-eslint/pull/6274): Switches most AST properties marked as `?: boolean` to `: boolean`, as well as some properties marked as `?:` optional to ` | undefined`. This results in more predictable AST node object shapes. +- [chore(typescript-estree): remove visitor-keys backwards compat export](https://github.com/typescript-eslint/typescript-eslint/pull/6242): `visitorKeys` can now only be imported from `@typescript-eslint/visitor-keys`. Previously it was also re-exported by `@typescript-eslint/utils`. +- [feat: add package.json exports for public packages](https://github.com/typescript-eslint/typescript-eslint/pull/6458): `@typescript-eslint/*` packages now use `exports` to prevent importing internal file paths. + ## Appreciation We'd like to extend a sincere _thank you_ to everybody who pitched in to make typescript-eslint v6 possible. From 035f249db964a3ece57ff2055f8dfc26fff6dc19 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Thu, 23 Feb 2023 02:07:19 -0500 Subject: [PATCH 08/14] Removed an hourglass, and one nit --- .../blog/2023-03-07-announcing-typescript-eslint-v6-beta.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/website/blog/2023-03-07-announcing-typescript-eslint-v6-beta.md b/packages/website/blog/2023-03-07-announcing-typescript-eslint-v6-beta.md index 126bfe24ee1f..c497dcbb82e6 100644 --- a/packages/website/blog/2023-03-07-announcing-typescript-eslint-v6-beta.md +++ b/packages/website/blog/2023-03-07-announcing-typescript-eslint-v6-beta.md @@ -67,7 +67,7 @@ However, some users correctly noted two flaws in that approach: - Strict rules that didn't require type checking were lumped in with those that did. - _Stylistic_ best practices were lumped in with rules that actually find bugs. -As a result, we've reworked the configurations provided by typescript-eslint into the two sections: +As a result, we've reworked the configurations provided by typescript-eslint into these two groups: - Functional rule configurations, for best best practices and code correctness: - **`plugin:@typescript-eslint/recommended`**: Recommended rules that you can drop in without additional configuration. @@ -269,7 +269,7 @@ For more information, see: - [feat: remove semantically invalid properties from TSEnumDeclaration, TSInterfaceDeclaration and TSModuleDeclaration](https://github.com/typescript-eslint/typescript-eslint/pull/4863): Removes some properties from those AST node types that should generally not have existed to begin with. - [fix(utils): removed TRuleListener generic from the createRule](https://github.com/typescript-eslint/typescript-eslint/pull/5036): Makes `createRule`-created rules more portable in the type system. - [feat(utils): remove (ts-)eslint-scope types](https://github.com/typescript-eslint/typescript-eslint/pull/5256): Removes no-longer-useful `TSESLintScope` types from the `@typescript-eslint/utils` package. -- ⏳ [fix: rename typeParameters to typeArguments where needed](https://github.com/typescript-eslint/typescript-eslint/pull/5384): corrects the names of AST properties that were called _parameters_ instead of _arguments_. +- [fix: rename typeParameters to typeArguments where needed](https://github.com/typescript-eslint/typescript-eslint/pull/5384): corrects the names of AST properties that were called _parameters_ instead of _arguments_. - To recap the terminology: - An _argument_ is something you provide to a recipient, such as a type provided explicitly to a call expression. - A _parameter_ is how the recipient receives what you provide, such as a function declaration's generic type parameter. From 5f9c1af4830c79cf7e3bc85509b4f0da12e177b6 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Thu, 23 Feb 2023 21:33:05 -0500 Subject: [PATCH 09/14] Fix casing and spelling issues --- .cspell.json | 1 + .markdownlint.json | 4 ++++ .../blog/2023-03-07-announcing-typescript-eslint-v6-beta.md | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.cspell.json b/.cspell.json index 21ca6f8fc237..683337145c03 100644 --- a/.cspell.json +++ b/.cspell.json @@ -72,6 +72,7 @@ "esquery", "esrecurse", "estree", + "falsiness", "globby", "IDE's", "IIFE", diff --git a/.markdownlint.json b/.markdownlint.json index 05206c4297d1..e94fcbda05ab 100644 --- a/.markdownlint.json +++ b/.markdownlint.json @@ -99,10 +99,14 @@ // MD044/proper-names - Proper names should have the correct capitalization "MD044": { "names": [ + "eslint-scope", + "eslint-plugin", + "eslint-recommended", "ESLint", "JavaScript", "TSLint", "typescript-eslint", + "typescript-estree", "TypeScript" ], "code_blocks": false diff --git a/packages/website/blog/2023-03-07-announcing-typescript-eslint-v6-beta.md b/packages/website/blog/2023-03-07-announcing-typescript-eslint-v6-beta.md index c497dcbb82e6..d30fd60a9914 100644 --- a/packages/website/blog/2023-03-07-announcing-typescript-eslint-v6-beta.md +++ b/packages/website/blog/2023-03-07-announcing-typescript-eslint-v6-beta.md @@ -278,7 +278,7 @@ For more information, see: - [feat: remove partial type-information program](https://github.com/typescript-eslint/typescript-eslint/pull/6066): When user configurations don't provide a `parserOptions.project`, parser services will no longer include a `program` with incomplete type information. `program` will be `null` instead. - [feat(experimental-utils): console.warn on import of experimental-utils](https://github.com/typescript-eslint/typescript-eslint/pull/6179): The `@typescript-eslint/experimental-utils` package has since been renamed to `@typescript-eslint/utils`. The old package name now includes a `console.warn` message to indicate you should switch to the new package name. - As a result, the `errorOnTypeScriptSyntacticAndSemanticIssues` option will no longer be allowed if `parserOptions.project` is not provided. -- ⏳ [feat(typescript-estree): remove optionality from AST boolean properties](https://github.com/typescript-eslint/typescript-eslint/pull/6274): Switches most AST properties marked as `?: boolean` to `: boolean`, as well as some properties marked as `?:` optional to ` | undefined`. This results in more predictable AST node object shapes. +- ⏳ [feat(typescript-estree): remove optionality from AST boolean properties](https://github.com/typescript-eslint/typescript-eslint/pull/6274): Switches most AST properties marked as `?: boolean` to `: boolean`, as well as some properties marked as `?:` optional to `| undefined`. This results in more predictable AST node object shapes. - [chore(typescript-estree): remove visitor-keys backwards compat export](https://github.com/typescript-eslint/typescript-eslint/pull/6242): `visitorKeys` can now only be imported from `@typescript-eslint/visitor-keys`. Previously it was also re-exported by `@typescript-eslint/utils`. - [feat: add package.json exports for public packages](https://github.com/typescript-eslint/typescript-eslint/pull/6458): `@typescript-eslint/*` packages now use `exports` to prevent importing internal file paths. From 7e8604ca51aa7b68e93f88c329513151d74a2412 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Thu, 23 Feb 2023 21:36:48 -0500 Subject: [PATCH 10/14] Re-correct TypeScript-ESTree spelling --- .markdownlint.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.markdownlint.json b/.markdownlint.json index e94fcbda05ab..f5b6d46d80e5 100644 --- a/.markdownlint.json +++ b/.markdownlint.json @@ -107,6 +107,7 @@ "TSLint", "typescript-eslint", "typescript-estree", + "TypeScript-ESTree", "TypeScript" ], "code_blocks": false From 71e180e6558cadd9a2a3bdd69e5b1b3bece65e44 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Sat, 11 Mar 2023 18:10:15 -0500 Subject: [PATCH 11/14] Mention names and v6 channel --- ...07-announcing-typescript-eslint-v6-beta.md | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/packages/website/blog/2023-03-07-announcing-typescript-eslint-v6-beta.md b/packages/website/blog/2023-03-07-announcing-typescript-eslint-v6-beta.md index d30fd60a9914..975ed5821470 100644 --- a/packages/website/blog/2023-03-07-announcing-typescript-eslint-v6-beta.md +++ b/packages/website/blog/2023-03-07-announcing-typescript-eslint-v6-beta.md @@ -21,9 +21,7 @@ Our plan for typescript-eslint v6 is to: 3. Release a stable version summer of 2023 Nothing mentioned in this blog post is set in stone. -If you feel passionately about any of the choices we've made here -positively or negatively- then do let us know on [the typescript-eslint Discord's `v6` channel](https://hi.joshuakgoldberg.com)! - - +If you feel passionately about any of the choices we've made here -positively or negatively- then do let us know on [the typescript-eslint Discord's `v6` channel](https://discord.com/channels/1026804805894672454/1084245444676292688)! ## Trying Out v6 @@ -162,7 +160,7 @@ If you author any ESLint plugins or other tools that interact with TypeScript sy It includes some breaking changes that you may need to accommodate for. :::tip -If you're having trouble working with the changes, please let us know on [the typescript-eslint Discord's `v6` channel](https://hi.joshuakgoldberg.com)! +If you're having trouble working with the changes, please let us know on [the typescript-eslint Discord's `v6` channel](https://discord.com/channels/1026804805894672454/1084245444676292688)! ::: ### Type Checker Wrapper APIs @@ -285,12 +283,22 @@ For more information, see: ## Appreciation We'd like to extend a sincere _thank you_ to everybody who pitched in to make typescript-eslint v6 possible. -We couldn't have done it without you! - -See the [v6.0.0 pull request](https://github.com/typescript-eslint/typescript-eslint/pull/5886) for a list of collaborators and merged pull request commits. -> Beware: there are >400k line changes across >1.5k files. -> The github.com file viewer generally cannot handle viewing the _Files_ tab. +- Ourselves on the maintenance team: + - [Armano](https://github.com/armano2) + - [Brad Zacher](https://github.com/bradzacher) + - [James Henry](https://github.com/JamesHenry) + - [Josh Goldberg](https://github.com/JoshuaKGoldberg) + - [Joshua Chen](https://github.com/Josh-Cena) +- Community contributors whose PRs were merged into the 6.0.0 release: + - [Bryan Mishkin](https://github.com/bmish) + - [fisker Cheung](https://github.com/fisker) + - [Juan García](https://github.com/juank1809) + - [Kevin Ball](https://github.com/kball) + - [Marek Dědič](https://github.com/marekdedic) + - [Mateusz Burzyński](https://github.com/Andarist) + +See the [v6.0.0 milestone](https://github.com/typescript-eslint/typescript-eslint/milestone/8) for the list of issues and associated merged pull requests. ## Supporting typescript-eslint From 566ad2f5ad8b796417f3b2286068fdf075ed9564 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Sat, 11 Mar 2023 18:10:29 -0500 Subject: [PATCH 12/14] Switch date to 13th --- ...beta.md => 2023-03-13-announcing-typescript-eslint-v6-beta.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/website/blog/{2023-03-07-announcing-typescript-eslint-v6-beta.md => 2023-03-13-announcing-typescript-eslint-v6-beta.md} (100%) diff --git a/packages/website/blog/2023-03-07-announcing-typescript-eslint-v6-beta.md b/packages/website/blog/2023-03-13-announcing-typescript-eslint-v6-beta.md similarity index 100% rename from packages/website/blog/2023-03-07-announcing-typescript-eslint-v6-beta.md rename to packages/website/blog/2023-03-13-announcing-typescript-eslint-v6-beta.md From 183cc47f760eb3a06f201cec02db3e54ca2ea2c2 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Sat, 11 Mar 2023 18:14:27 -0500 Subject: [PATCH 13/14] Spelling fixes --- .cspell.json | 1 + .../blog/2023-03-13-announcing-typescript-eslint-v6-beta.md | 2 ++ 2 files changed, 3 insertions(+) diff --git a/.cspell.json b/.cspell.json index 683337145c03..b8e07af48645 100644 --- a/.cspell.json +++ b/.cspell.json @@ -42,6 +42,7 @@ "Airbnb", "Airbnb's", "ambiently", + "Armano", "astexplorer", "ASTs", "autofix", diff --git a/packages/website/blog/2023-03-13-announcing-typescript-eslint-v6-beta.md b/packages/website/blog/2023-03-13-announcing-typescript-eslint-v6-beta.md index 975ed5821470..3062f18fbc58 100644 --- a/packages/website/blog/2023-03-13-announcing-typescript-eslint-v6-beta.md +++ b/packages/website/blog/2023-03-13-announcing-typescript-eslint-v6-beta.md @@ -291,12 +291,14 @@ We'd like to extend a sincere _thank you_ to everybody who pitched in to make ty - [Josh Goldberg](https://github.com/JoshuaKGoldberg) - [Joshua Chen](https://github.com/Josh-Cena) - Community contributors whose PRs were merged into the 6.0.0 release: + - [Bryan Mishkin](https://github.com/bmish) - [fisker Cheung](https://github.com/fisker) - [Juan García](https://github.com/juank1809) - [Kevin Ball](https://github.com/kball) - [Marek Dědič](https://github.com/marekdedic) - [Mateusz Burzyński](https://github.com/Andarist) + See the [v6.0.0 milestone](https://github.com/typescript-eslint/typescript-eslint/milestone/8) for the list of issues and associated merged pull requests. From bf95384caf4644786de3b4eb6d0a0b02bfc4a17c Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Mon, 13 Mar 2023 15:13:03 -0400 Subject: [PATCH 14/14] Jaaaaaames Henry --- .../blog/2023-03-13-announcing-typescript-eslint-v6-beta.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/website/blog/2023-03-13-announcing-typescript-eslint-v6-beta.md b/packages/website/blog/2023-03-13-announcing-typescript-eslint-v6-beta.md index 3062f18fbc58..feb68f087dfc 100644 --- a/packages/website/blog/2023-03-13-announcing-typescript-eslint-v6-beta.md +++ b/packages/website/blog/2023-03-13-announcing-typescript-eslint-v6-beta.md @@ -202,8 +202,8 @@ In typescript-eslint v6, we've added a set of wrapper APIs on the `services: Par For now, the available wrapper APIs are: -- `getSymbolAtLocation`: directly passes an ESTree node to TypeScript's `checker.getSymbolAtLocation` -- `getTypeAtLocation`: directly passes an ESTree node to TypeScript's `checker.getTypeAtLocation` +- `getSymbolAtLocation`: passes an ESTree's equivalent TypeScript node to `checker.getSymbolAtLocation` +- `getTypeAtLocation`: passes an ESTree node's equivalent TypeScript node to `checker.getTypeAtLocation` We hope these wrapper APIs make it more convenient to write lint rules that rely on the awesome power of TypeScript's type checking. In the future, we may add more wrapper APIs, and may even add internal caching to those APIs to improve performance.