8000 feat(eslint-plugin): replace ban-types with no-restricted-types, no-unsafe-function-type, no-wrapper-object-types by JoshuaKGoldberg · Pull Request #9102 · typescript-eslint/typescript-eslint · GitHub
[go: up one dir, main page]

Skip to content

feat(eslint-plugin): replace ban-types with no-restricted-types, no-unsafe-function-type, no-wrapper-object-types #9102

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
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
452fe6d
feat(eslint-plugin): add no-restricted-types, no-uppercase-alias-type…
JoshuaKGoldberg May 15, 2024
1791e4f
Fix lint issues
JoshuaKGoldberg May 15, 2024
7c606fc
Apply suggestions from code review
JoshuaKGoldberg May 24, 2024
7734da7
Kirk suggestions
JoshuaKGoldberg May 24, 2024
d1127f5
yarn test -u
JoshuaKGoldberg May 24, 2024
aae4be7
test: fix tests for useProgramFromProjectService
JoshuaKGoldberg May 26, 2024
c411cdb
Rename to no-wrapper-object-types
JoshuaKGoldberg May 26, 2024
057b34a
excess myObject in docs
JoshuaKGoldberg May 26, 2024
d4baaef
Fix rules/index.ts
JoshuaKGoldberg May 26, 2024
f25f333
Merge branch 'v8' into no-ban-types-splitup
JoshuaKGoldberg May 26, 2024
88bd835
Clarify ban-types deprecation message
JoshuaKGoldberg May 27, 2024
874e97a
Remove ban-types altogether
JoshuaKGoldberg May 27, 2024
1a854f1
fix website build with permalink to ban-types
JoshuaKGoldberg May 27, 2024
48afe9d
Merge branch 'v8'
JoshuaKGoldberg May 27, 2024
2bfa14b
Update configs
JoshuaKGoldberg May 27, 2024
43fa798
Apply suggestions from code review
JoshuaKGoldberg May 28, 2024
c220790
fix ban-types.md
JoshuaKGoldberg May 28, 2024
732e812
Update packages/eslint-plugin/docs/rules/no-wrapper-object-types.mdx
JoshuaKGoldberg May 31, 2024
b5e5410
lil nit
JoshuaKGoldberg May 31, 2024
45df4d6
remove callable type
JoshuaKGoldberg May 31, 2024
fec4311
Split out no-unsafe-function-type too
JoshuaKGoldberg Jun 2, 2024
01a6f4d
Merge branch 'v8'
JoshuaKGoldberg Jun 2, 2024
e357c8e
fix /blog link in ban-types.md
JoshuaKGoldberg Jun 2, 2024
2508d84
Mention args: never
JoshuaKGoldberg Jun 2, 2024
2a32c12
Regenerate configs
JoshuaKGoldberg Jun 2, 2024
41db8fe
lil phrasing nit
JoshuaKGoldberg Jun 2, 2024
22bec9d
chore: fix snapshot
JoshuaKGoldberg Jun 3, 2024
3858d65
fix lint complaint
JoshuaKGoldberg Jun 3, 2024
e078105
Address feedback
JoshuaKGoldberg Jun 10, 2024
e22cbb9
Apply suggestions from code review
JoshuaKGoldberg Jun 12, 2024
8872bdc
Mention concepts and equality
JoshuaKGoldberg Jun 12, 2024
2e33cee
fix: scope analysis
JoshuaKGoldberg Jun 12, 2024
184e4ee
ban-types.md rule mentions
JoshuaKGoldberg Jun 12, 2024
cad7178
Merge branch 'v8'
JoshuaKGoldberg Jun 13, 2024
7d73bf3
fix no-restricted-types docs test
JoshuaKGoldberg Jun 13, 2024
75543e9
wrong list, kronk
JoshuaKGoldberg Jun 13, 2024
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/maintenance/Issues.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ For enhancements meant to limit which kinds of nodes the rule targets, mark the
#### 🚀 New Rules

We're generally accepting of new rules that meet the above feature request criteria.
The biggest exception is rules that can roughly be implemented with [`@typescript-eslint/ban-types`](/rules/ban-types) and/or [`no-restricted-syntax`](https://eslint.org/docs/latest/rules/no-restricted-syntax).
The biggest exception is rules that can roughly be implemented with [`@typescript-eslint/no-restricted-types`](/rules/no-restricted-types) and/or [`no-restricted-syntax`](https://eslint.org/docs/latest/rules/no-restricted-syntax).

## Pruning Old Issues

Expand Down
54 changes: 27 additions & 27 deletions packages/eslint-plugin/TSLINT_RULE_ALTERNATIVES.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,32 +15,32 @@ It lists all TSLint rules along side rules from the ESLint ecosystem that are th

### TypeScript-specific

| TSLint rule | | ESLint rule |
| --------------------------------- | :-: | ---------------------------------------------------- |
| [`adjacent-overload-signatures`] | ✅ | [`@typescript-eslint/adjacent-overload-signatures`] |
| [`ban-ts-ignore`] | ✅ | [`@typescript-eslint/ban-ts-comment`] |
| [`ban-types`] | 🌓 | [`@typescript-eslint/ban-types`]<sup>[1]</sup> |
| [`invalid-void`] | ✅ | [`@typescript-eslint/no-invalid-void-type`] |
| [`member-access`] | ✅ | [`@typescript-eslint/explicit-member-accessibility`] |
| [`member-ordering`] | ✅ | [`@typescript-eslint/member-ordering`] |
| [`no-any`] | ✅ | [`@typescript-eslint/no-explicit-any`] |
| [`no-empty-interface`] | ✅ | [`@typescript-eslint/no-empty-object-type`] |
| [`no-import-side-effect`] | 🔌 | [`import/no-unassigned-import`] |
| [`no-inferrable-types`] | ✅ | [`@typescript-eslint/no-inferrable-types`] |
| [`no-internal-module`] | ✅ | [`@typescript-eslint/prefer-namespace-keyword`] |
| [`no-magic-numbers`] | ✅ | [`@typescript-eslint/no-magic-numbers`] |
| [`no-namespace`] | ✅ | [`@typescript-eslint/no-namespace`] |
| [`no-non-null-assertion`] | ✅ | [`@typescript-eslint/no-non-null-assertion`] |
| [`no-parameter-reassignment`] | ✅ | [`no-param-reassign`][no-param-reassign] |
| [`no-reference`] | ✅ | [`@typescript-eslint/triple-slash-reference`] |
| [`no-unnecessary-type-assertion`] | ✅ | [`@typescript-eslint/no-unnecessary-type-assertion`] |
| [`no-var-requires`] | ✅ | [`@typescript-eslint/no-var-requires`] |
| [`only-arrow-functions`] | 🔌 | [`prefer-arrow/prefer-arrow-functions`] |
| [`prefer-for-of`] | ✅ | [`@typescript-eslint/prefer-for-of`] |
| [`promise-function-async`] | ✅ | [`@typescript-eslint/promise-function-async`] |
| [`typedef-whitespace`] | ✅ | [`@typescript-eslint/type-annotation-spacing`] |
| [`typedef`] | ✅ | [`@typescript-eslint/typedef`] |
| [`unified-signatures`] | ✅ | [`@typescript-eslint/unified-signatures`] |
| TSLint rule | | ESLint rule |
| --------------------------------- | :-: | -------------------------------------------------------- |
| [`adjacent-overload-signatures`] | ✅ | [`@typescript-eslint/adjacent-overload-signatures`] |
| [`ban-ts-ignore`] | ✅ | [`@typescript-eslint/ban-ts-comment`] |
| [`ban-types`] | 🌓 | [`@typescript-eslint/no-restricted-types`]<sup>[1]</sup> |
| [`invalid-void`] | ✅ | [`@typescript-eslint/no-invalid-void-type`] |
| [`member-access`] | ✅ | [`@typescript-eslint/explicit-member-accessibility`] |
| [`member-ordering`] | ✅ | [`@typescript-eslint/member-ordering`] |
| [`no-any`] | ✅ | [`@typescript-eslint/no-explicit-any`] |
| [`no-empty-interface`] | ✅ | [`@typescript-eslint/no-empty-object-type`] |
| [`no-import-side-effect`] | 🔌 | [`import/no-unassigned-import`] |
| [`no-inferrable-types`] | ✅ | [`@typescript-eslint/no-inferrable-types`] |
| [`no-internal-module`] | ✅ | [`@typescript-eslint/prefer-namespace-keyword`] |
| [`no-magic-numbers`] | ✅ | [`@typescript-eslint/no-magic-numbers`] |
| [`no-namespace`] | ✅ | [`@typescript-eslint/no-namespace`] |
| [`no-non-null-assertion`] | ✅ | [`@typescript-eslint/no-non-null-assertion`] |
| [`no-parameter-reassignment`] | ✅ | [`no-param-reassign`][no-param-reassign] |
| [`no-reference`] | ✅ | [`@typescript-eslint/triple-slash-reference`] |
| [`no-unnecessary-type-assertion`] | ✅ | [`@typescript-eslint/no-unnecessary-type-assertion`] |
| [`no-var-requires`] | ✅ | [`@typescript-eslint/no-var-requires`] |
| [`only-arrow-functions`] | 🔌 | [`prefer-arrow/prefer-arrow-functions`] |
| [`prefer-for-of`] | ✅ | [`@typescript-eslint/prefer-for-of`] |
| [`promise-function-async`] | ✅ | [`@typescript-eslint/promise-function-async`] |
| [`typedef-whitespace`] | ✅ | [`@typescript-eslint/type-annotation-spacing`] |
| [`typedef`] | ✅ | [`@typescript-eslint/typedef`] |
| [`unified-signatures`] | ✅ | [`@typescript-eslint/unified-signatures`] |

<sup>[1]</sup> The ESLint rule only supports exact string matching, rather than regular expressions<br>

Expand Down Expand Up @@ -595,7 +595,7 @@ Relevant plugins: [`chai-expect-keywords`](https://github.com/gavinaiken/eslint-

[`@typescript-eslint/adjacent-overload-signatures`]: https://typescript-eslint.io/rules/adjacent-overload-signatures
[`@typescript-eslint/await-thenable`]: https://typescript-eslint.io/rules/await-thenable
[`@typescript-eslint/ban-types`]: https://typescript-eslint.io/rules/ban-types
[`@typescript-eslint/no-restricted-types`]: https://typescript-eslint.io/rules/no-restricted-types
[`@typescript-eslint/ban-ts-comment`]: https://typescript-eslint.io/rules/ban-ts-comment
[`@typescript-eslint/class-methods-use-this`]: https://typescript-eslint.io/rules/class-methods-use-this
[`@typescript-eslint/consistent-type-assertions`]: https://typescript-eslint.io/rules/consistent-type-assertions
Expand Down
22 changes: 22 additions & 0 deletions packages/eslint-plugin/docs/rules/ban-types.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
:::danger Deprecated
Copy link
Member

Choose a reason for hiding this comment

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

press-f-pay-respect.gif


The old `ban-types` rule encompassed multiple areas of functionality, and so has been split into several rules.

**[`no-restricted-types`](./no-restricted-types.mdx)** is the new rule for banning a configurable list of type names.
It has no options enabled by default and is akin to rules like [`no-restricted-globals`](https://eslint.org/docs/latest/rules/no-restricted-globals), [`no-restricted-properties`](https://eslint.org/docs/latest/rules/no-restricted-properties), and [`no-restricted-syntax`](https://eslint.org/docs/latest/rules/no-restricted-syntax).

The default options from `ban-types` are now covered by:

- **[`no-empty-object-type`](./no-empty-object-type.mdx)**: banning the built-in `{}` type in confusing locations
- **[`no-unsafe-function-type`](./no-unsafe-function-type.mdx)**: banning the built-in `Function`
- **[`no-wrapper-object-types`](./no-wrapper-object-types.mdx)**: banning `Object` and built-in class wrappers such as `Number`

`ban-types` itself is removed in typescript-eslint v8.
See [Announcing typescript-eslint v8 Beta](/blog/announcing-typescript-eslint-v8-beta) for more details.
:::

<!-- This doc file has been left on purpose because `ban-types` is a well-known
rule. This exists to help direct people to the replacement rules.

Note that there is no actual way to get to this page in the normal navigation,
so end-users will only be able to get to this page from the search bar. -->
133 changes: 0 additions & 133 deletions packages/eslint-plugin/docs/rules/ban-types.mdx

This file was deleted.

71 changes: 71 additions & 0 deletions packages/eslint-plugin/docs/rules/no-restricted-types.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
---
description: 'Disallow certain types.'
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

> 🛑 This file is source code, not the primary documentation location! 🛑
>
> See **https://typescript-eslint.io/rules/no-restricted-types** for documentation.

It can sometimes be useful to ban specific types from being used in type annotations.
For example, a project might be migrating from using one type to another, and want to ban references to the old type.

This rule can be configured to ban a list of specific types and can suggest alternatives.
Note that it does not ban the corresponding runtime objects from being used.

## Options

### `types`

An object whose keys are the types you want to ban, and the values are error messages.

The type can either be a type name literal (`OldType`) or a a type name with generic parameter instantiation(s) (`OldType<MyArgument>`).

The values can be:

- A string, which is the error message to be reported; or
- `false` to specifically un-ban this type (useful when you are using `extendDefaults`); or
- An object with the following properties:
- `message: string`: the message to display when the type is matched.
- `fixWith?: string`: a string to replace the banned type with when the fixer is run. If this is omitted, no fix will be done.
- `suggest?: string[]`: a list of suggested replacements for the banned type.

Example configuration:

```jsonc
{
"@typescript-eslint/no-restricted-types": [
"error",
{
"types": {
// add a custom message to help explain why not to use it
"OldType": "Don't use OldType because it is unsafe",

// add a custom message, and tell the plugin how to fix it
"OldAPI": {
"message": "Use NewAPI instead",
"fixWith": "NewAPI",
},

// add a custom message, and tell the plugin how to suggest a fix
"SoonToBeOldAPI": {
"message": "Use NewAPI instead",
"suggest": ["NewAPIOne", "NewAPITwo"],
},
},
},
],
}
```

## When Not To Use It

If you have no need to ban specific types from being used in type annotations, you don't need this rule.

## Related To

- [`no-empty-object-type`](./no-empty-object-type.mdx)
- [`no-unsafe-function-type`](./no-unsafe-function-type.mdx)
- [`no-wrapper-object-types`](./no-wrapper-object-types.mdx)
63 changes: 63 additions & 0 deletions packages/eslint-plugin/docs/rules/no-unsafe-function-type.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---
description: 'Disallow using the unsafe built-in Function type.'
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

> 🛑 This file is source code, not the primary documentation location! 🛑
>
> See **https://typescript-eslint.io/rules/no-unsafe-function-type** for documentation.

TypeScript's built-in `Function` type allows being called with any number of arguments and returns type `any`.
`Function` also allows classes or plain objects that happen to possess all properties of the `Function` class.
It's generally better to specify function parameters and return types with the function type syntax.

"Catch-all" function types include:

- `() => void`: a function that has no parameters and whose return is ignored
- `(...args: never) => unknown`: a "top type" for functions that can be assigned any function type, but can't be called

Examples of code for this rule:

<Tabs>
<TabItem value="❌ Incorrect">

```ts
let noParametersOrReturn: Function;
noParametersOrReturn = () => {};

let stringToNumber: Function;
stringToNumber = (text: string) => text.length;

let identity: Function;
identity = value => value;
```

</TabItem>
<TabItem value="✅ Correct">

```ts
let noParametersOrReturn: () => void;
noParametersOrReturn = () => {};

let stringToNumber: (text: string) => number;
stringToNumber = text => text.length;

let identity: <T>(value: T) => T;
identity = value => value;
```

</TabItem>
</Tabs>

## When Not To Use It

If your project is still onboarding to TypeScript, it might be difficult to fully replace all unsafe `Function` types with more precise function types.
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule.

## Related To

- [`no-empty-object-type`](./no-empty-object-type.mdx)
- [`no-restricted-types`](./no-restricted-types.mdx)
- [`no-wrapper-object-types`](./no-wrapper-object-types.mdx)
Loading
Loading
0