116 lines
3.6 KiB
Plaintext
116 lines
3.6 KiB
Plaintext
---
|
|
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!
|
|
:::
|
|
|
|
## 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)
|