no-unnecessary-type-parameters
Disallow type parameters that aren't used multiple times.
Extending "plugin:@typescript-eslint/strict-type-checked"
in an ESLint configuration enables this rule.
This rule requires type information to run.
This rule forbids type parameters that aren't used multiple times in a function, method, or class definition.
Type parameters relate two types.
If a type parameter is only used 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.
This rule was recently added, and has a surprising amount of hidden complexity compared to most of our rules. If you encounter unexpected behavior with it, please check closely the Limitations section below and our issue tracker. If you don't see your case covered, please reach out to us!
module.exports = {
"rules": {
"@typescript-eslint/no-unnecessary-type-parameters": "error"
}
};
Try this rule in the playground ↗
Examples
- ❌ Incorrect
- ✅ Correct
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]);
}
Open in Playgroundfunction 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];
}
Open in PlaygroundLimitations
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:
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
.
Options
This rule is not configurable.
When Not To Use It
This rule will report on functions that use type parameters solely to test types, for example:
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
- Effective TypeScript: The Golden Rule of Generics
Related To
- eslint-plugin-etc's
no-misused-generics
- wotan's
no-misused-generics
- DefinitelyTyped-tools'
no-unnecessary-generics
Type checked lint rules are more powerful than traditional lint rules, but also require configuring type checked linting.
See Troubleshooting > Linting with Type Information > Performance if you experience performance degredations after enabling type checked rules.