Skip to content

docs: final updates to v8 beta post #9627

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,18 @@
"Airbnb's",
"allowdefaultprojectforfiles",
"ambiently",
"Arka",
"Armano",
"astexplorer",
"Astro",
"ASTs",
"Aubut",
"autofix",
"autofixers",
"autofixes",
"automations",
"auvred",
"Bachman",
"backticks",
"bigint",
"bivariant",
Expand All @@ -69,6 +72,7 @@
"camelcase",
"canonicalize",
"Cena",
"Chaudhuri",
"codebases",
"Codecov",
"contravariant",
Expand All @@ -89,6 +93,8 @@
"estree",
"falsiness",
"globby",
"Hasegawa",
"Huchedé",
"IDE's",
"ignoreconditionaltests",
"IIFE",
Expand All @@ -101,6 +107,7 @@
"markdownlint",
"metastring",
"multipass",
"Nandi",
"necroing",
"nocheck",
"noninteractive",
Expand All @@ -116,6 +123,7 @@
"pluggable",
"postprocess",
"postprocessor",
"Pratim",
"preact",
"Premade",
"prettier's",
Expand All @@ -128,9 +136,11 @@
"reimplement",
"resync",
"ROADMAP",
"Rosenwasser",
"ruleset",
"rulesets",
"serializers",
"Sheetal",
"Sourcegraph",
"stringification",
"stringifying",
Expand All @@ -157,6 +167,7 @@
"useprojectservice",
"Waiblinger",
"warnonunsupportedtypescriptversion",
"Yukihiro",
"Zacher"
],
"overrides": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,6 @@ 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 v7 to v8.

> ⏳ indicates a change that has been scheduled for v8 but not yet released.
> We'll update this blog post as the corresponding pull requests land.

### ESLint v9 Support

typescript-eslint v8 ships with full support for ESLint v9.
Expand Down Expand Up @@ -163,7 +160,7 @@ If your ESLint configuration contains many `rules` configurations, we suggest th
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/downgrade to "warn" any rules creating too many errors for you to fix — with _"TODO"_ comments linking to tracking issues/tickets to re-enable them
5. In your ESLint configuration and/or with inline `eslint-disable` comments, turn off / downgrade to "warn" any rules creating too many errors for you to fix — with _"TODO"_ comments linking to tracking issues/tickets to re-enable them

:::

Expand All @@ -172,11 +169,11 @@ If your ESLint configuration contains many `rules` configurations, we suggest th
Several rules are changed in significant enough ways to be considered breaking changes:

- [Rules: Deprecate prefer-ts-expect-error in favor of ban-ts-comment](https://github.com/typescript-eslint/typescript-eslint/issues/8333)
- If you have [`@typescript-eslint/prefer-ts-expect-error`](/rules/prefer-ts-expect-error) manually enabled, remove that, and instead either use a [recommended config](/users/configs) or manually enable [`@typescript-eslint/ban-ts-comment`](/rules/ban-ts-comment)
- If you have [`@typescript-eslint/prefer-ts-expect-error`](/rules/prefer-ts-expect-error) manually enabled, remove that, and instead either use a [recommended config](/users/configs) or manually enable [`@typescript-eslint/ban-ts-comment`](/rules/ban-ts-comment).
- [chore(eslint-plugin): deprecate no-var-requires in favor of no-require-imports](https://github.com/typescript-eslint/typescript-eslint/pull/8334)
- If you have [`@typescript-eslint/no-var-requires`](/rules/no-var-requires) manually enabled, remove that, and instead either use a [recommended config](/users/configs) or manually enable [`@typescript-eslint/no-require-imports`](/rules/no-require-imports)
- If you have [`@typescript-eslint/no-var-requires`](/rules/no-var-requires) manually enabled, remove that, and instead either use a [recommended config](/users/configs) or manually enable [`@typescript-eslint/no-require-imports`](/rules/no-require-imports).
- [feat(eslint-plugin): remove deprecated no-throw-literal rule](https://github.com/typescript-eslint/typescript-eslint/issues/9083)
- If you have [`@typescript-eslint/no-throw-literal`](https://typescript-eslint.io/rules/no-throw-literal) manually enabled, remove that, and instead either use a [recommended config](/users/configs) or manually enable [`@typescript-eslint/only-throw-error`](/rules/only-throw-error)
- If you have [`@typescript-eslint/no-throw-literal`](https://typescript-eslint.io/rules/no-throw-literal) manually enabled, remove that, and instead either use a [recommended config](/users/configs) or manually enable [`@typescript-eslint/only-throw-error`](/rules/only-throw-error).
- [feat(eslint-plugin): [no-useless-template-literals] rename to no-useless-template-expression (deprecate no-useless-template-literals)](https://github.com/typescript-eslint/typescript-eslint/pull/8821) and [fix: no-useless-template-expression -> no-unnecessary-template-expression](https://github.com/typescript-eslint/typescript-eslint/pull/9174)
- Find-and-replace text from `no-useless-template-literals` to `no-unnecessary-template-expression`
- [feat(eslint-plugin): deprecate no-loss-of-precision extension rule](https://github.com/typescript-eslint/typescript-eslint/pull/8832)
Expand Down Expand Up @@ -215,10 +212,10 @@ To migrate to the new rules:
- If you were disabling the ban on `{}`, consider enabling [`@typescript-eslint/no-empty-object-type`](https://v8--typescript-eslint.netlify.app/rules/no-empty-object-type), as it allows some cases of `{}` that were previously banned.
- If you were banning any configurable types lists, provide a similar configuration to [`no-restricted-types`](https://v8--typescript-eslint.netlify.app/rules/no-restricted-types).
- If you have [`@typescript-eslint/ban-types`](/rules/ban-types) manually enabled, it will no longer ban:
- `{}` or `object`: use a [recommended config](/users/configs) or manually enable [`@typescript-eslint/no-empty-object-type`](https://v8--typescript-eslint.netlify.app/rules/no-empty-object-type)
- `Function`: use a [recommended config](/users/configs) or manually enable [`@typescript-eslint/no-unsafe-function-type`](https://v8--typescript-eslint.netlify.app/rules/no-unsafe-function-type)
- `Number` or other built-in uppercase types: use a [recommended config](/users/configs) or manually enable [`@typescript-eslint/no-wrapper-object-types`](https://v8--typescript-eslint.netlify.app/rules/no-wrapper-object-types)
- If you have [`@typescript-eslint/no-empty-interface`](/rules/no-empty-interface) manually enabled, remove that, and instead either use a [recommended config](/users/configs) or manually enable [`@typescript-eslint/no-empty-object-type`](https://v8--typescript-eslint.netlify.app/rules/no-empty-object-type)
- `{}` or `object`: use a [recommended config](/users/configs) or manually enable [`@typescript-eslint/no-empty-object-type`](https://v8--typescript-eslint.netlify.app/rules/no-empty-object-type).
- `Function`: use a [recommended config](/users/configs) or manually enable [`@typescript-eslint/no-unsafe-function-type`](https://v8--typescript-eslint.netlify.app/rules/no-unsafe-function-type).
- `Number` or other built-in uppercase types: use a [recommended config](/users/configs) or manually enable [`@typescript-eslint/no-wrapper-object-types`](https://v8--typescript-eslint.netlify.app/rules/no-wrapper-object-types).
- If you have [`@typescript-eslint/no-empty-interface`](/rules/no-empty-interface) manually enabled, remove that, and instead either use a [recommended config](/users/configs) or manually enable [`@typescript-eslint/no-empty-object-type`](https://v8--typescript-eslint.netlify.app/rules/no-empty-object-type).

For more details, see the issues and pull requests that split apart the `ban-types` rule:

Expand All @@ -229,8 +226,7 @@ For more details, see the issues and pull requests that split apart the `ban-typ

### Tooling Breaking Changes

- ⏳ [Enhancement: Error if configuration options aren't provided as expected](https://github.com/typescript-eslint/typescript-eslint/issues/6403)
- This should only cause errors if you had an invalid config.
- ~[Enhancement: Error if configuration options aren't provided as expected](https://github.com/typescript-eslint/typescript-eslint/issues/6403)~: postponed to a future major version
- [fix(typescript-estree): enable dot globs for project by default](https://github.com/typescript-eslint/typescript-eslint/pull/8818)
- This will cause any `parserOptions.project` globs to match dot (`.`) directories.
If you don't want to match them then use a more specific set of globs, or switch to `parserOptions.projectService`.
Expand Down Expand Up @@ -267,7 +263,7 @@ If you're having trouble working with the changes, please let us know on [the ty
These changes are to 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.

- [Enhancement: add strict parent types for nodes that have well-defined parents](https://github.com/typescript-eslint/typescript-eslint/issues/6225)
- [Enhancement: add strict parent types for nodes that have well-defined parents](https://github.com/typescript-eslint/typescript-eslint/issues/6225)
- This will help you remove some unnecessary conditions - we suggest using `@typescript-eslint/no-unnecessary-condition` to help find the unnecessary checks!
- [feat(typescript-estree): split TSMappedType typeParameter into constraint and key](https://github.com/typescript-eslint/typescript-eslint/pull/7065)
- If your code handles mapped types, change from `node.typeParameter.constraint` to `node.constraint` and from `node.typeParameter.name` to `node.key`
Expand Down Expand Up @@ -311,13 +307,85 @@ createRule({

See [feat(utils): allow specifying additional rule meta.docs in RuleCreator](https://github.com/typescript-eslint/typescript-eslint/pull/9025) for more details.

### Flat Configuration `RuleTester`

:::note
This breaking change was missed in the initial versions of this blog post.
:::

The `RuleTester` provided by [`@typescript-eslint/rule-tester`](/packages/rule-tester) is a fork of ESLint's `RuleTester`.
In typescript-eslint v7 and earlier, `RuleTester`'s constructor allowed providing legacy "eslintrc" options -- mirroring ESLint v8 and earlier.
In typescript-eslint v8, `RuleTester`'s constructor now instead allows providing new "flat" config options -- mirroring ESLint v9.

Per ESLint flat configs, any parser configurations you provide will need to be inside a `languageOptions` property:

```ts title="rule.test.ts"
import { RuleTester } from '@typescript-eslint/rule-tester

const ruleTester = new RuleTester({
// Add this line
languageOptions: {
parserOptions: {
tsconfigRootDir: import.meta.dirname,
},
// Add this line
},
});
```

Any `parser` you provide will need to be the parser itself, rather than a string name of the package:

```ts title="rule.test.ts"
import { RuleTester } from '@typescript-eslint/rule-tester
// Add this line
import jsoncParser from "jsonc-eslint-parser";

const ruleTester = new RuleTester({
// Add this line
languageOptions: {
// Add this line
parser: jsoncParser,
// Remove this line
parser: "jsonc-eslint-parser",
// Add this line
},
});
```

This change brings typescript-eslint's `RuleTester` in line with ESLint's `RuleTester` and flat config.
In doing so, it changes two `parserOptions` defaults:

- `ecmaVersion`: from `5` to `'latest'`
- `sourceType`: from `'script'` to `'module'`

If you were specifying either or both of those in your tests, you likely can now omit them:

```ts title="rule.test.ts"
import { RuleTester } from '@typescript-eslint/rule-tester

// Add this line
const ruleTester = new RuleTester();
// Removed lines start
const ruleTester = new RuleTester({
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
},
});
// Removed lines end
```

For more details, see:

- [ESLint > Migrate to 9.0.0 > `FlatRuleTester` is now `RuleTester`](https://eslint.org/docs/latest/use/migrate-to-9.0.0#-flatruletester-is-now-ruletester)
- [typescript-eslint > feat(rule-tester): switched to flat config](https://github.com/typescript-eslint/typescript-eslint/pull/9603)

### Support for multi-pass fixes in `RuleTester`

The `RuleTester` provided by `@typescript-eslint/rule-tester` is a fork of ESLint's `RuleTester`.
One limitation of the original `RuleTester` is that it is not possible to verify the individual applied fixes when a rule provides multiple rounds of fixes.
[The original `RuleTester` applies only the first fix](https://eslint.org/docs/latest/integrate/nodejs-api#testing-fixes) when there is conflict between two fixes.
One limitation of ESLint's `RuleTester` is that it is not possible to verify the individual applied fixes when a rule provides multiple rounds of fixes.
[ESLint's `RuleTester` applies only the first fix](https://eslint.org/docs/latest/integrate/nodejs-api#testing-fixes) when there is conflict between two fixes.

In typescript-eslint v8, `RuleTester` tries to apply all possible fixes for each test case.
In typescript-eslint v8, the typescript-eslint `RuleTester` tries to apply all possible fixes for each test case.

If your rule tests had some test cases that required multi-pass fixes, you will see some test failures.
To fix these failures, provide an array of strings for `output` which specifies the output after each fix pass.
Expand Down Expand Up @@ -351,7 +419,7 @@ See [[rule-tester] support multipass fixes](https://github.com/typescript-eslint

### Other Developer-Facing Breaking Changes

- [Repo: Rule [options] parameter should be non-nullable if defaultOptions exists](https://github.com/typescript-eslint/typescript-eslint/issues/5439)
- ~[Repo: Rule [options] parameter should be non-nullable if defaultOptions exists](https://github.com/typescript-eslint/typescript-eslint/issues/5439)~: blocked on external features in ESLint and TypeScript
- [feat(parser): always enable comment, loc, range, tokens](https://github.com/typescript-eslint/typescript-eslint/pull/8617)
- If you were manually calling `@typescript-eslint/parser` functions, those options are no longer necessary to provide
- [chore(type-utils)!: remove IsNullableTypeOptions interface](https://github.com/typescript-eslint/typescript-eslint/pull/8934)
Expand All @@ -376,12 +444,16 @@ We'd like to extend a sincere _thank you_ to everybody who pitched in to make ty
- [Joshua Chen](https://github.com/Josh-Cena)
- [Kirk Waiblinger](https://github.com/kirkwaiblinger)
- Community contributors whose PRs were merged into the 8.0.0 release:
<!-- cspell:disable -->
- [Abraham Guo](https://github.com/abrahamguo)
- [Arka Pratim Chaudhuri](https://github.com/arka1002)
- [Christopher Aubut](https://github.com/higherorderfunctor)
- [Collin Bachman](https://github.com/bachmacintosh)
- [Thomas Huchedé](https://github.com/thuchede)
- [Victor Lin](https://github.com/yepitschunked)
- [Yukihiro Hasegawa](https://github.com/y-hsgw)
- _(more to come as PRs are merged!)_
<!-- cspell:enable -->
- Members of the TypeScript team who helped with performance issues:
- [Jake Bailey](https://github.com/jakebailey)
- [Sheetal Nandi](https://github.com/sheetalkamat)
- [Daniel Rosenwasser](https://github.com/DanielRosenwasser)

See the [v8.0.0 milestone](https://github.com/typescript-eslint/typescript-eslint/milestone/9) for the list of issues and associated merged pull requests.
Loading