-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
feat(eslint-plugin): [no-unnecessary-type-parameters] initial implementation #8173
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
Changes from all commits
bff3ffb
b3a2ba2
fecd305
fd14c5c
dea56bf
3cdeeee
20c9399
edf54c5
c2e3788
87d30fe
66ad82a
9ff6aae
43b0424
a5fcfc4
1c06ec1
2194a12
8ebf34a
1244a13
3be30d5
438a645
7731a88
fbe18a9
81523ab
b95883b
aa025a7
318db40
77bc70e
5f0b849
89ba35c
40199a8
c542524
74cddeb
8420f28
a54b494
88dc28f
983a4bc
3366958
0555244
3862291
7499dc7
11915b5
260b396
d914f7f
a1a97b8
b03a80c
9815ac0
bc63572
9a6535a
c9e35b6
7a36d05
98f37e6
e429dae
f56e842
2ba8c00
24390d7
095b3a6
a4ffa49
e798241
c038426
a9ec7b2
edf4870
45cce54
2ae5440
21dbb31
4cbb510
cfaf2a8
a305a82
5f327dc
8e4f484
9ec35a2
77b36ea
62cc2aa
4b9a1fa
6d3e600
bf65e22
e177a33
5253856
3bfe101
2e9035a
78c165b
03866c1
6dde5d0
2ecc5e7
db2df24
2d45a50
ffa1a49
08bc190
3b79444
c9ceb9d
1bc3c97
bb907e2
33b974d
b56976e
b7cef73
d56daf2
b683c99
20aa80b
cffeff1
dfd35e3
9b4b595
00adcb3
86f4a6a
7139e45
605d683
5bb38fc
c318218
6e7ebd2
8070b5e
f80df34
55a56ff
7bdd202
be5dcea
0498cfa
76b82dc
937df84
b73bcfb
5efa3f5
1dbc1dc
c14abab
80fb537
c2240b1
8eb089f
a0029c0
0584edd
cd1d307
14d86d1
5d00bae
b81d1db
359bc18
d333a09
c4e9ebc
bd1f7cc
82de7b7
7092762
ca9b4d3
b6cf082
7b23880
e21aaa7
b954bf0
02f8c7f
dd366cc
daba7df
366f564
327b288
e855e9f
398c496
721faa1
838ab2d
6d2322b
72b5a96
0da4c6e
1c7ef11
581937d
53d2ab8
38716b3
cd0ec0d
92dbb4f
88ca7c8
61922bd
467172b
69b820f
c485f96
a09c18f
c1f3cf5
a8f2dd3
c2384b3
e9ac84e
a85881b
db84ba1
6763e63
ed24717
8d9e650
74c04c7
d33970f
9ca4f1d
94ee0fd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
--- | ||
description: 'Disallow type parameters that only appear once.' | ||
--- | ||
|
||
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-unnecessary-type-parameters** for documentation. | ||
|
||
This rule forbids type parameters that only appear once in a function, method, or class definition. | ||
|
||
Type parameters relate two types. | ||
If a type parameter only appears once, then it is not relating anything. | ||
It can usually be replaced with explicit types such as `unknown`. | ||
|
||
At best unnecessary type parameters make code harder to read. | ||
At worst they can be used to disguise unsafe type assertions. | ||
|
||
:::warning Early Stage | ||
This rule was recently added to typescript-eslint and still considered experimental. | ||
It might change significantly between minor versions. | ||
Please try it out and give us feedback! | ||
::: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From chats with @bradzacher and @Josh-Cena: we're roughly ready to merge this rule, but it's still somewhat experimental / something-we-haven't-tried-ourselves-before. So instead of putting in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (for posterity: the chats were about adding a notice; I felt icky after the fact about both having a notice and leaving it in |
||
|
||
## Examples | ||
|
||
<Tabs> | ||
<TabItem value="❌ Incorrect"> | ||
|
||
```ts | ||
function second<A, B>(a: A, b: B): B { | ||
return b; | ||
} | ||
|
||
function parseJSON<T>(input: string): T { | ||
return JSON.parse(input); | ||
} | ||
|
||
function printProperty<T, K extends keyof T>(obj: T, key: K) { | ||
console.log(obj[key]); | ||
} | ||
``` | ||
|
||
</TabItem> | ||
<TabItem value="✅ Correct"> | ||
|
||
```ts | ||
function second<B>(a: unknown, b: B): B { | ||
return b; | ||
} | ||
|
||
function parseJSON(input: string): unknown { | ||
return JSON.parse(input); | ||
} | ||
|
||
function printProperty<T>(obj: T, key: keyof T) { | ||
console.log(obj[key]); | ||
} | ||
|
||
// T appears twice: in the type of arg and as the return type | ||
function identity<T>(arg: T): T { | ||
return arg; | ||
} | ||
|
||
// T appears twice: "keyof T" and in the inferred return type (T[K]). | ||
// K appears twice: "key: K" and in the inferred return type (T[K]). | ||
function getProperty<T, K extends keyof T>(obj: T, key: K) { | ||
return obj[key]; | ||
} | ||
``` | ||
|
||
</TabItem> | ||
</Tabs> | ||
|
||
## Limitations | ||
|
||
Note that this rule allows any type parameter that is used multiple times, even if those uses are via a type argument. | ||
For example, the following `T` is used multiple times by virtue of being in an `Array`, even though its name only appears once after declaration: | ||
|
||
```ts | ||
declare function createStateHistory<T>(): T[]; | ||
``` | ||
|
||
This is because the type parameter `T` relates multiple methods in the `T[]` together, making it used more than once. | ||
|
||
Therefore, this rule won't report on type parameters used as a type argument. | ||
That includes type arguments given to global types such as `Array` (including the `T[]` shorthand and in tuples), `Map`, and `Set`. | ||
|
||
## When Not To Use It | ||
|
||
This rule will report on functions that use type parameters solely to test types, for example: | ||
|
||
```ts | ||
function assertType<T>(arg: T) {} | ||
|
||
assertType<number>(123); | ||
assertType<number>('abc'); | ||
// ~~~~~ | ||
// Argument of type 'string' is not assignable to parameter of type 'number'. | ||
``` | ||
|
||
If you're using this pattern then you'll want to disable this rule on files that test types. | ||
|
||
## Further Reading | ||
|
||
- TypeScript handbook: [Type Parameters Should Appear Twice](https://microsoft.github.io/TypeScript-New-Handbook/everything/#type-parameters-should-appear-twice) | ||
- Effective TypeScript: [The Golden Rule of Generics](https://effectivetypescript.com/2020/08/12/generics-golden-rule/) | ||
|
||
## Related To | ||
|
||
- eslint-plugin-etc's [`no-misused-generics`](https://github.com/cartant/eslint-plugin-etc/blob/main/docs/rules/no-misused-generics.md) | ||
- wotan's [`no-misused-generics`](https://github.com/fimbullinter/wotan/blob/master/packages/mimir/docs/no-misused-generics.md) | ||
- DefinitelyTyped-tools' [`no-unnecessary-generics`](https://github.com/microsoft/DefinitelyTyped-tools/blob/main/packages/eslint-plugin/docs/rules/no-unnecessary-generics.md) |
Uh oh!
There was an error while loading. Please reload this page.