Skip to content

Commit 57e4120

Browse files
feat(eslint-plugin): [no-deprecation] add rule (typescript-eslint#9783)
* WIP: no-deprecation * I think it's mostly there * A couple small issues * Start on docs * Generated configs and ran tests * Remove deprecation/deprecation and disable ours as needed * Remove deprecation/deprecation and disable ours as needed * updated inline comments * Fixed up call likes * Fixed up exports * The repo is passing now * lil comment * Apply suggestions from code review Co-authored-by: Kirk Waiblinger <kirk.waiblinger@gmail.com> * Update comments and Related To * yarn test -u * Explicitly mention deprecated/deprecated * no more see * Throw error for jsDocParsingMode --------- Co-authored-by: Kirk Waiblinger <kirk.waiblinger@gmail.com>
1 parent 6250dab commit 57e4120

30 files changed

+1718
-129
lines changed

docs/packages/TypeScript_ESLint.mdx

+1-2
Original file line numberDiff line numberDiff line change
@@ -254,8 +254,7 @@ export default tseslint.config({
254254
extends: [tseslint.configs.disableTypeChecked],
255255
rules: {
256256
// turn off other type-aware rules
257-
'deprecation/deprecation': 'off',
258-
'@typescript-eslint/internal/no-poorly-typed-ts-props': 'off',
257+
'other-plugin/typed-rule': 'off',
259258

260259
// turn off rules that don't apply to JS code
261260
'@typescript-eslint/explicit-function-return-type': 'off',

eslint.config.mjs

-8
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { fixupConfigRules, fixupPluginRules } from '@eslint/compat';
66
import { FlatCompat } from '@eslint/eslintrc';
77
import eslint from '@eslint/js';
88
import tseslintInternalPlugin from '@typescript-eslint/eslint-plugin-internal';
9-
import deprecationPlugin from 'eslint-plugin-deprecation';
109
import eslintCommentsPlugin from 'eslint-plugin-eslint-comments';
1110
import eslintPluginPlugin from 'eslint-plugin-eslint-plugin';
1211
import importPlugin from 'eslint-plugin-import';
@@ -32,9 +31,6 @@ export default tseslint.config(
3231
plugins: {
3332
['@typescript-eslint']: tseslint.plugin,
3433
['@typescript-eslint/internal']: tseslintInternalPlugin,
35-
// https://github.com/gund/eslint-plugin-deprecation/issues/78
36-
// https://github.com/typescript-eslint/typescript-eslint/issues/8988
37-
['deprecation']: fixupPluginRules(deprecationPlugin),
3834
['eslint-comments']: eslintCommentsPlugin,
3935
['eslint-plugin']: eslintPluginPlugin,
4036
// https://github.com/import-js/eslint-plugin-import/issues/2948
@@ -96,9 +92,6 @@ export default tseslint.config(
9692
},
9793
linterOptions: { reportUnusedDisableDirectives: 'error' },
9894
rules: {
99-
// make sure we're not leveraging any deprecated APIs
100-
'deprecation/deprecation': 'error',
101-
10295
// TODO: https://github.com/typescript-eslint/typescript-eslint/issues/8538
10396
'@typescript-eslint/no-confusing-void-expression': 'off',
10497

@@ -335,7 +328,6 @@ export default tseslint.config(
335328
extends: [tseslint.configs.disableTypeChecked],
336329
rules: {
337330
// turn off other type-aware rules
338-
'deprecation/deprecation': 'off',
339331
'@typescript-eslint/internal/no-poorly-typed-ts-props': 'off',
340332

341333
// turn off rules that don't apply to JS code

package.json

-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@
9393
"cspell": "^8.6.1",
9494
"downlevel-dts": ">=0.11.0",
9595
"eslint": "^9.3.0",
96-
"eslint-plugin-deprecation": "^2.0.0",
9796
"eslint-plugin-eslint-comments": "^3.2.0",
9897
"eslint-plugin-eslint-plugin": "^6.2.0",
9998
"eslint-plugin-import": "^2.29.1",

packages/eslint-plugin/TSLINT_RULE_ALTERNATIVES.md

+1-2
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ It lists all TSLint rules along side rules from the ESLint ecosystem that are th
122122
| TSLint rule | | ESLint rule |
123123
| ---------------------------- | :-: | -------------------------------------------------- |
124124
| [`cyclomatic-complexity`] | 🌟 | [`complexity`][complexity] |
125-
| [`deprecation`] | 🔌 | [`deprecation/deprecation`] |
125+
| [`deprecation`] | | [`@typescript-eslint/no-deprecated`] |
126126
| [`eofline`] | 🌟 | [`eol-last`][eol-last] |
127127
| [`indent`] || [`@typescript-eslint/indent`] or [Prettier] |
128128
| [`linebreak-style`] | 🌟 | [`linebreak-style`][linebreak-style] or [Prettier] |
@@ -724,5 +724,4 @@ Relevant plugins: [`chai-expect-keywords`](https://github.com/gavinaiken/eslint-
724724
[`jest/no-focused-tests`]: https://github.com/jest-community/eslint-plugin-jest/blob/main/docs/rules/no-focused-tests.md
725725
[`jsx-a11y/heading-has-content`]: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/heading-has-content.md
726726
[`lodash/chaining`]: https://github.com/wix/eslint-plugin-lodash/blob/master/docs/rules/chaining.md
727-
[`deprecation/deprecation`]: https://github.com/gund/eslint-plugin-deprecation
728727
[`desktop/insecure-random`]: https://github.com/desktop/desktop/blob/development/eslint-rules/insecure-random.js
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
---
2+
description: 'Disallow using code marked as `@deprecated`.'
3+
---
4+
5+
import Tabs from '@theme/Tabs';
6+
import TabItem from '@theme/TabItem';
7+
8+
> 🛑 This file is source code, not the primary documentation location! 🛑
9+
>
10+
> See **https://typescript-eslint.io/rules/no-deprecated** for documentation.
11+
12+
The [JSDoc `@deprecated` tag](https://jsdoc.app/tags-deprecated) can be used to document some piece of code being deprecated.
13+
It's best to avoid using code marked as deprecated.
14+
This rule reports on any references to code marked as `@deprecated`.
15+
16+
:::note
17+
[TypeScript recognizes the `@deprecated` tag](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html#deprecated) and visualizes deprecated code with a ~strikethrough~.
18+
However, TypeScript doesn't report type errors for deprecated code on its own.
19+
:::
20+
21+
## Examples
22+
23+
<Tabs>
24+
<TabItem value="❌ Incorrect">
25+
26+
```ts
27+
/** @deprecated Use apiV2 instead. */
28+
declare function apiV1(): Promise<string>;
29+
30+
declare function apiV2(): Promise<string>;
31+
32+
await apiV1();
33+
```
34+
35+
```ts
36+
import { parse } from 'node:url';
37+
38+
// 'parse' is deprecated. Use the WHATWG URL API instead.
39+
const url = parse('/foo');
40+
```
41+
42+
</TabItem>
43+
<TabItem value="✅ Correct">
44+
45+
```ts
46+
/** @deprecated Use apiV2 instead. */
47+
declare function apiV1(): Promise<string>;
48+
49+
declare function apiV2(): Promise<string>;
50+
51+
await apiV2();
52+
```
53+
54+
```ts
55+
// Modern Node.js API, uses `new URL()`
56+
const url2 = new URL('/foo', 'http://www.example.com');
57+
```
58+
59+
</TabItem>
60+
</Tabs>
61+
62+
## When Not To Use It
63+
64+
If portions of your project heavily use deprecated APIs and have no plan for moving to non-deprecated ones, you might want to disable this rule in those portions.
65+
66+
## Related To
67+
68+
- [`import/no-deprecated`](https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-deprecated.md) and [`import-x/no-deprecated`](https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-deprecated.md): Does not use type information, but does also support [TomDoc](http://tomdoc.org)
69+
- [`eslint-plugin-deprecation`](https://github.com/gund/eslint-plugin-deprecation) ([`deprecation/deprecation`](https://github.com/gund/eslint-plugin-deprecation?tab=readme-ov-file#rules)): Predecessor to this rule in a separate plugin

packages/eslint-plugin/src/configs/all.ts

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ export = {
4646
'@typescript-eslint/no-base-to-string': 'error',
4747
'@typescript-eslint/no-confusing-non-null-assertion': 'error',
4848
'@typescript-eslint/no-confusing-void-expression': 'error',
49+
'@typescript-eslint/no-deprecated': 'error',
4950
'no-dupe-class-members': 'off',
5051
'@typescript-eslint/no-dupe-class-members': 'error',
5152
'@typescript-eslint/no-duplicate-enum-values': 'error',

packages/eslint-plugin/src/configs/disable-type-checked.ts

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export = {
1818
'@typescript-eslint/no-array-delete': 'off',
1919
'@typescript-eslint/no-base-to-string': 'off',
2020
'@typescript-eslint/no-confusing-void-expression': 'off',
21+
'@typescript-eslint/no-deprecated': 'off',
2122
'@typescript-eslint/no-duplicate-type-constituents': 'off',
2223
'@typescript-eslint/no-floating-promises': 'off',
2324
'@typescript-eslint/no-for-in-array': 'off',

packages/eslint-plugin/src/configs/strict-type-checked-only.ts

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export = {
1414
'@typescript-eslint/no-array-delete': 'error',
1515
'@typescript-eslint/no-base-to-string': 'error',
1616
'@typescript-eslint/no-confusing-void-expression': 'error',
17+
'@typescript-eslint/no-deprecated': 'error',
1718
'@typescript-eslint/no-duplicate-type-constituents': 'error',
1819
'@typescript-eslint/no-floating-promises': 'error',
1920
'@typescript-eslint/no-for-in-array': 'error',

packages/eslint-plugin/src/configs/strict-type-checked.ts

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export = {
2020
'@typescript-eslint/no-array-delete': 'error',
2121
'@typescript-eslint/no-base-to-string': 'error',
2222
'@typescript-eslint/no-confusing-void-expression': 'error',
23+
'@typescript-eslint/no-deprecated': 'error',
2324
'@typescript-eslint/no-duplicate-enum-values': 'error',
2425
'@typescript-eslint/no-duplicate-type-constituents': 'error',
2526
'@typescript-eslint/no-dynamic-delete': 'error',

packages/eslint-plugin/src/rules/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import noArrayDelete from './no-array-delete';
2929
import noBaseToString from './no-base-to-string';
3030
import confusingNonNullAssertionLikeNotEqual from './no-confusing-non-null-assertion';
3131
import noConfusingVoidExpression from './no-confusing-void-expression';
32+
import noDeprecated from './no-deprecated';
3233
import noDupeClassMembers from './no-dupe-class-members';
3334
import noDuplicateEnumValues from './no-duplicate-enum-values';
3435
import noDuplicateTypeConstituents from './no-duplicate-type-constituents';
@@ -157,6 +158,7 @@ export default {
157158
'no-base-to-string': noBaseToString,
158159
'no-confusing-non-null-assertion': confusingNonNullAssertionLikeNotEqual,
159160
'no-confusing-void-expression': noConfusingVoidExpression,
161+
'no-deprecated': noDeprecated,
160162
'no-dupe-class-members': noDupeClassMembers,
161163
'no-duplicate-enum-values': noDuplicateEnumValues,
162164
'no-duplicate-type-constituents': noDuplicateTypeConstituents,

0 commit comments

Comments
 (0)