Skip to content

docs: refreshed typescript-eslint package docs, especially tseslint.config #10725

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
2 changes: 1 addition & 1 deletion docs/getting-started/Quickstart.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ The `.mjs` extension makes the file use the [ES modules (ESM)](https://developer

#### Details

- `tseslint.config(...)` is an **_optional_** helper function — [read more about it here](../packages/TypeScript_ESLint.mdx#config).
- `tseslint.config(...)` is an **_optional_** helper function — see [`typescript-eslint`'s `config(...)`](../packages/TypeScript_ESLint.mdx#config).
- `'@eslint/js'` / `eslint.configs.recommended` turns on [eslint's recommended config](https://www.npmjs.com/package/@eslint/js).
- `tseslint.configs.recommended` turns on [our recommended config](../users/Shared_Configurations.mdx#recommended).

Expand Down
256 changes: 130 additions & 126 deletions docs/packages/TypeScript_ESLint.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,32 +16,22 @@ This package is the main entrypoint that you can use to consume our tooling with

This package exports the following:

| name | description |
| --------- | --------------------------------------------------------------- |
| `config` | A utility function for creating type-safe flat configs |
| `configs` | [Our eslint (flat) configs](../users/Shared_Configurations.mdx) |
| `parser` | [Our parser](./Parser.mdx) |
| `plugin` | [Our plugin](./ESLint_Plugin.mdx) |
| Name | Description |
| --------- | -------------------------------------------------------------------------------------- |
| `config` | A utility function for creating type-safe flat configs -- see [`config(...)`](#config) |
| `configs` | [Shared ESLint (flat) configs](../users/Shared_Configurations.mdx) |
| `parser` | A re-export of [`@typescript-eslint/parser`](./Parser.mdx) |
| `plugin` | A re-export of [`@typescript-eslint/eslint-plugin`](./ESLint_Plugin.mdx) |

## Installation

```bash npm2yarn
npm i typescript-eslint
```

### Migrating from "legacy" config setups

If you're migrating from a "legacy" `.eslintrc` configuration setup you likely have our plugin and parser installed separately. This package includes these as dependencies so you can freely uninstall your local references:

```bash npm2yarn
npm un @typescript-eslint/parser @typescript-eslint/eslint-plugin
```

For more information on migrating from a "legacy" config setup, see [ESLint's Configuration Migration Guide](https://eslint.org/docs/latest/use/configure/migration-guide).

## Usage

The simplest usage of this package would be:
We recommend getting started by using `tseslint.config` helper function in your ESLint config:

```js title="eslint.config.mjs"
// @ts-check
Expand All @@ -55,111 +45,15 @@ export default tseslint.config(
);
```

This config file exports a flat config that enables both the [core eslint recommended config](https://www.npmjs.com/package/@eslint/js) and [our recommended config](../users/Shared_Configurations.mdx#recommended).

For more information on the `tseslint.config` function [see `config(...)` below](#config).

### Advanced usage

#### Manually configuring our plugin and parser

You can declare our plugin and parser in your config via this package, for example:

```js title="eslint.config.mjs"
// @ts-check

import eslint from '@eslint/js';
import jestPlugin from 'eslint-plugin-jest';
import tseslint from 'typescript-eslint';

export default tseslint.config({
plugins: {
// highlight-next-line
'@typescript-eslint': tseslint.plugin,
},
languageOptions: {
// highlight-next-line
parser: tseslint.parser,
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
rules: {
'@typescript-eslint/no-unsafe-argument': 'error',
'@typescript-eslint/no-unsafe-assignment': 'error',
'@typescript-eslint/no-unsafe-call': 'error',
'@typescript-eslint/no-unsafe-member-access': 'error',
'@typescript-eslint/no-unsafe-return': 'error',
},
});
```

:::warning
We **_strongly_** recommend declaring our plugin with the namespace `@typescript-eslint` as shown above. If you use our shared configs this is the namespace that they use. This has been the standard namespace for our plugin for many years and is what users are most familiar with.

You may choose a different namespace - but note that currently [flat configs allow the same plugin to be registered, configured, and have duplicate reports under multiple namespaces](https://github.com/eslint/eslint/discussions/17766).
:::

#### Usage with other plugins

Below is a more complex example of how you might use our tooling with flat configs. This config:

- Ignores `build`/`dist` folders from being linted
- Enables our plugin, our parser, and type-aware linting with a few of our popular type-aware rules
- Disables type-aware linting on JS files
- Enables the recommended `eslint-plugin-jest` rules on test files only

```js title="eslint.config.mjs"
// @ts-check

import eslint from '@eslint/js';
import jestPlugin from 'eslint-plugin-jest';
import tseslint from 'typescript-eslint';

export default tseslint.config(
{
// config with just ignores is the replacement for `.eslintignore`
ignores: ['**/build/**', '**/dist/**', 'src/some/file/to/ignore.ts'],
},
eslint.configs.recommended,
{
plugins: {
'@typescript-eslint': tseslint.plugin,
jest: jestPlugin,
},
languageOptions: {
parser: tseslint.parser,
parserOptions: {
projectService: true,
},
},
rules: {
'@typescript-eslint/no-unsafe-argument': 'error',
'@typescript-eslint/no-unsafe-assignment': 'error',
'@typescript-eslint/no-unsafe-call': 'error',
'@typescript-eslint/no-unsafe-member-access': 'error',
'@typescript-eslint/no-unsafe-return': 'error',
},
},
{
// disable type-aware linting on JS files
files: ['**/*.js'],
extends: [tseslint.configs.disableTypeChecked],
},
{
// enable jest rules on test files
files: ['test/**'],
extends: [jestPlugin.configs['flat/recommended']],
},
);
```
This config file exports a flat config that enables both the [core ESLint recommended config](https://www.npmjs.com/package/@eslint/js) and [our recommended config](../users/Shared_Configurations.mdx#recommended).

## `config(...)`
### `config(...)`

The `config` function is a [variadic](https://en.wikipedia.org/wiki/Variadic_function) [identity function](https://en.wikipedia.org/wiki/Identity_function) which is a fancy way of saying that it's a function with a spread argument that accepts any number flat config objects and returns the objects unchanged. It exists as a way to quickly and easily provide types for your flat config file without the need for JSDoc type comments.
`tseslint.config(...)` takes in any number of ESLint config objects, each of which may additionally include an `extends` array of configs to extend.
`tseslint.config(...)` returns the equivalent ESLint config of applying the rest of the settings for each extension.

By using this function you will get autocomplete and documentation for all config properties in addition to TypeScript errors, should you provide invalid values.
By using this function you will get autocomplete and documentation for all config properties.
Additionally, if you provide invalid values, it can trigger informative TypeScript type errors.

<Tabs>
<TabItem value="With helper">
Expand Down Expand Up @@ -204,12 +98,15 @@ export default [
</Tabs>

:::note
We _**strongly**_ recommend using this utility to improve the config authoring experience — however it is entirely optional. By choosing not to use it you lose editor autocomplete and type checking for config files but otherwise it _will not_ impact your ability to use our tooling.
We _**strongly**_ recommend using this utility to improve the config authoring experience — however it is entirely optional.
By choosing not to use it you lose editor autocomplete and type checking for config files.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and also the extends key 🤷

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now. eslint/rfcs#126 was accepted and eslint/eslint#19116 is in Implementing status. I think mentioning extends won't be accurate for very long.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, but what's scary to me about not mentioning it at all is that eslint/eslint#19116 will have extends with different semantics. Is there a way to preempt that? I'm ok with whatever you think is best here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, true... proposal: can we split this out as a followup issue? I don't have a strong gut feeling on the right way to preempt this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Otherwise it _will not_ impact your ability to use our tooling.
:::

### Flat config `extends`
#### Flat config `extends`

The `tseslint.config` utility function also adds handling for the `extends` property on flat config objects. This allows you to more easily extend shared configs for specific file patterns whilst also overriding rules/options provided by those configs:
The `tseslint.config` utility function also adds handling for the `extends` property on flat config objects.
This allows you to more easily extend shared configs for specific file patterns whilst also overriding rules/options provided by those configs:

```js
export default tseslint.config({
Expand All @@ -220,7 +117,7 @@ export default tseslint.config({
],
rules: {
'@typescript-eslint/array-type': 'error',
'@typescript-eslint/consistent-type-imports': 'error',
// ...
},
});

Expand All @@ -238,15 +135,15 @@ export default [
files: ['**/*.ts'],
rules: {
'@typescript-eslint/array-type': 'error',
'@typescript-eslint/consistent-type-imports': 'error',
// ...
},
},
];
```

We found that this is a pretty common operation when writing ESLint configs which is why we provided this convenience property.
We found that this is a common operation when writing ESLint configs which is why we provided this convenience property.

For example in codebases with type-aware linting a config object like this is a very common way to disable TS-specific linting setups on JS files:
For example, in codebases with type-aware linting, a config object like the following is a common way to disable TypeScript-specific linting setups on JavaScript files:

```js
export default tseslint.config({
Expand All @@ -261,3 +158,110 @@ export default tseslint.config({
},
});
```

### Manual usage

[typescript-eslint's recommended and stylistic configurations](../users/configs) specify typescript-eslint `parser` and `plugin` options for you, so there is no need to manually provide those.
However, in complex ESLint configurations, you may find yourself manually specifying those options yourself.

#### Manually configuring our plugin and parser

You can declare our plugin and parser in your config via this package, for example:

```js title="eslint.config.mjs"
// @ts-check

import eslint from '@eslint/js';
import jestPlugin from 'eslint-plugin-jest';
import tseslint from 'typescript-eslint';

export default tseslint.config({
plugins: {
// highlight-next-line
'@typescript-eslint': tseslint.plugin,
},
languageOptions: {
// highlight-next-line
parser: tseslint.parser,
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
rules: {
'@typescript-eslint/no-floating-promises': 'error',
// ...
},
});
```

:::warning
We **_strongly_** recommend declaring our plugin with the namespace `@typescript-eslint` as shown above.
If you use our shared configs this is the namespace that they use.
This has been the standard namespace for our plugin for many years and is what users are most familiar with.

You may choose a different namespace - but note that currently [flat configs allow the same plugin to be registered, configured, and have duplicate reports under multiple namespaces](https://github.com/eslint/eslint/discussions/17766).
:::

### Usage with other plugins

Below is a more complex example of how you might use our tooling with flat configs.
This config:

- Ignores `build`/`dist` folders from being linted
- Enables our plugin, our parser, and type-aware linting with a few of our popular type-aware rules
- Disables type-aware linting on JS files
- Enables the recommended `eslint-plugin-jest` rules on test files only

```js title="eslint.config.mjs"
// @ts-check

import eslint from '@eslint/js';
import jestPlugin from 'eslint-plugin-jest';
import tseslint from 'typescript-eslint';

export default tseslint.config(
{
// config with just ignores is the replacement for `.eslintignore`
ignores: ['**/build/**', '**/dist/**', 'src/some/file/to/ignore.ts'],
},
eslint.configs.recommended,
{
plugins: {
'@typescript-eslint': tseslint.plugin,
jest: jestPlugin,
},
languageOptions: {
parser: tseslint.parser,
parserOptions: {
projectService: true,
},
},
rules: {
'@typescript-eslint/no-floating-promises': 'error',
// ...
},
},
{
// disable type-aware linting on JS files
files: ['**/*.js'],
extends: [tseslint.configs.disableTypeChecked],
},
{
// enable jest rules on test files
files: ['test/**'],
extends: [jestPlugin.configs['flat/recommended']],
},
);
```

## Migrating from legacy `.eslintrc` configs

If you're migrating from a legacy `.eslintrc` configuration setup you likely have our plugin and parser installed separately.
This package includes these as dependencies so you can freely uninstall your local references:

```bash npm2yarn
npm un @typescript-eslint/parser @typescript-eslint/eslint-plugin
```

For more information on migrating from a "legacy" config setup, see [ESLint's Configuration Migration Guide](https://eslint.org/docs/latest/use/configure/migration-guide).
Loading