Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork2.8k
feat(eslint-plugin): [no-unnecessary-type-parameters] special case tuples and parameter location arrays as single-use#9536
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Changes fromall commits
cd5e9a4
baadbe9
f655fef
3eeb08a
021f12c
6caeb43
bd6f08b
74b2e17
18f8951
4602ca7
e00f32f
366158d
6d386c5
9979cf9
8fea88e
d1563bd
fe7efb1
81a2260
9a82fb7
815aebf
2f26941
678e6b8
3d36117
667e715
13733da
89812f4
6f2e84d
4232c34
b957878
d7cb27e
38776d1
8b35cab
32ca4c7
544d9c8
34785bf
6cfb31b
c8cee06
18ba62b
a9f1684
2e1c31c
f185577
fed012a
c94a9de
015c68c
0eb9d8c
dd91489
286e7ae
ae4e523
48cfe54
0d1f8df
27f29e2
21cbd34
fc006d3
8a24eca
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -239,9 +239,17 @@ function isTypeParameterRepeatedInAST( | ||
const grandparent = skipConstituentsUpward( | ||
reference.identifier.parent.parent, | ||
); | ||
if ( | ||
grandparent.type === AST_NODE_TYPES.TSTypeParameterInstantiation && | ||
grandparent.params.includes(reference.identifier.parent) && | ||
// Array and ReadonlyArray must be handled carefully | ||
// let's defer the check to the type-aware phase | ||
!( | ||
grandparent.parent.type === AST_NODE_TYPES.TSTypeReference && | ||
grandparent.parent.typeName.type === AST_NODE_TYPES.Identifier && | ||
['Array', 'ReadonlyArray'].includes(grandparent.parent.typeName.name) | ||
) | ||
) { | ||
return true; | ||
} | ||
@@ -281,13 +289,13 @@ function countTypeParameterUsage( | ||
if (ts.isClassLike(node)) { | ||
for (const typeParameter of node.typeParameters) { | ||
collectTypeParameterUsageCounts(checker, typeParameter, counts, true); | ||
} | ||
for (const member of node.members) { | ||
collectTypeParameterUsageCounts(checker, member, counts, true); | ||
} | ||
} else { | ||
collectTypeParameterUsageCounts(checker, node, counts, false); | ||
} | ||
return counts; | ||
@@ -302,6 +310,7 @@ function collectTypeParameterUsageCounts( | ||
checker: ts.TypeChecker, | ||
node: ts.Node, | ||
foundIdentifierUsages: Map<ts.Identifier, number>, | ||
fromClass: boolean, // We are talking about the type parameters of a class or one of its methods | ||
): void { | ||
const visitedSymbolLists = new Set<ts.Symbol[]>(); | ||
const type = checker.getTypeAtLocation(node); | ||
@@ -325,6 +334,7 @@ function collectTypeParameterUsageCounts( | ||
function visitType( | ||
type: ts.Type | undefined, | ||
assumeMultipleUses: boolean, | ||
isReturnType = false, | ||
jfet97 marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
): void { | ||
// Seeing the same type > (threshold=3 ** 2) times indicates a likely | ||
// recursive type, like `type T = { [P in keyof T]: T }`. | ||
@@ -380,9 +390,23 @@ function collectTypeParameterUsageCounts( | ||
// Tuple types like `[K, V]` | ||
// Generic type references like `Map<K, V>` | ||
else if (tsutils.isTypeReference(type)) { | ||
for (const typeArgument of type.typeArguments ?? []) { | ||
// currently, if we are in a "class context", everything is accepted | ||
let thisAssumeMultipleUses = fromClass || assumeMultipleUses; | ||
// special cases - readonly arrays/tuples are considered only to use the | ||
// type parameter once. Mutable arrays/tuples are considered to use the | ||
// type parameter multiple times if and only if they are returned. | ||
// other kind of type references always count as multiple uses | ||
thisAssumeMultipleUses ||= tsutils.isTupleType(type.target) | ||
? isReturnType && !type.target.readonly | ||
: checker.isArrayType(type.target) | ||
? isReturnType && | ||
(type.symbol as ts.Symbol | undefined)?.getName() === 'Array' | ||
: true; | ||
visitType(typeArgument, thisAssumeMultipleUses, isReturnType); | ||
} | ||
} | ||
@@ -472,6 +496,7 @@ function collectTypeParameterUsageCounts( | ||
checker.getTypePredicateOfSignature(signature)?.type ?? | ||
signature.getReturnType(), | ||
false, | ||
true, | ||
); | ||
} | ||
Some generated files are not rendered by default. Learn more abouthow customized files appear on GitHub.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.