β¬ οΈ Back to Table of Contents
π no-unnecessary-type-constraint¶
π Analysis Summary¶
| Metric | Count |
|---|---|
| π§ Functions | 4 |
| π¦ Imports | 6 |
| π Type Aliases | 1 |
π Table of Contents¶
π οΈ File Location:¶
π packages/eslint-plugin/src/rules/no-unnecessary-type-constraint.ts
π€ Default Export¶
| Property | Value |
|---|---|
name |
'no-unnecessary-type-constraint' |
meta.type |
'suggestion' |
meta.docs.description |
'Disallow unnecessary constraints on generic types' |
meta.docs.recommended |
'recommended' |
meta.hasSuggestions |
true |
meta.messages.removeUnnecessaryConstraint |
'Remove the unnecessary {{constraint}} constraint.' |
meta.messages.unnecessaryConstraint |
'Constraining the generic type {{name}} to {{constraint}} does nothing and is unnecessary.' |
meta.schema |
[] |
defaultOptions |
[] |
Entry point: create β documented under Functions.
π¦ Imports¶
| Name | Source |
|---|---|
TSESLint |
@typescript-eslint/utils |
TSESTree |
@typescript-eslint/utils |
AST_NODE_TYPES |
@typescript-eslint/utils |
extname |
node:path |
MakeRequired |
../util |
createRule |
../util |
Functions¶
create(context: any): { ':not(ArrowFunctionExpression) > TSTypeParameterDeclarati⦶
Parameters:
contextany
Returns: { ':not(ArrowFunctionExpression) > TSTypeParameterDeclaration > TSTypeParameter[constraint]'(node: TypeParameterWithConstraint): void; 'ArrowFunctionExpression > TSTypeParameterDeclaration > TSTypeParameter[constraint]'(node: TypeParameterWithConstraint): void; }
Calls:
extname(filename).toLocaleLowerCasecheckRequiresGenericDeclarationDisambiguationunnecessaryConstraints.getcontext.sourceCode.getTokensAftercontext.reportfixer.replaceTextRangeshouldAddTrailingCommacheckNode
Internal Comments:
// In theory, we could use the type checker for more advanced constraint types... (x2)
// ...but in practice, these types are rare, and likely not worth requiring type info. (x2)
// https://github.com/typescript-eslint/typescript-eslint/pull/2516#discussion_r495731858 (x2)
// Only <T>() => {} would need trailing comma
Code
create(context) {
// In theory, we could use the type checker for more advanced constraint types...
// ...but in practice, these types are rare, and likely not worth requiring type info.
// https://github.com/typescript-eslint/typescript-eslint/pull/2516#discussion_r495731858
const unnecessaryConstraints = new Map([
[AST_NODE_TYPES.TSAnyKeyword, 'any'],
[AST_NODE_TYPES.TSUnknownKeyword, 'unknown'],
]);
function checkRequiresGenericDeclarationDisambiguation(
filename: string,
): boolean {
const pathExt = extname(filename).toLocaleLowerCase() as ts.Extension;
switch (pathExt) {
case ts.Extension.Cts:
case ts.Extension.Mts:
case ts.Extension.Tsx:
return true;
default:
return false;
}
}
const requiresGenericDeclarationDisambiguation =
checkRequiresGenericDeclarationDisambiguation(context.filename);
const checkNode = (
node: TypeParameterWithConstraint,
inArrowFunction: boolean,
): void => {
const constraint = unnecessaryConstraints.get(node.constraint.type);
function shouldAddTrailingComma(): boolean {
if (!inArrowFunction || !requiresGenericDeclarationDisambiguation) {
return false;
}
// Only <T>() => {} would need trailing comma
return (
(node.parent as TSESTree.TSTypeParameterDeclaration).params.length ===
1 &&
context.sourceCode.getTokensAfter(node)[0].value !== ',' &&
!node.default
);
}
if (constraint) {
context.report({
node,
messageId: 'unnecessaryConstraint',
data: {
name: node.name.name,
constraint,
},
suggest: [
{
messageId: 'removeUnnecessaryConstraint',
data: {
constraint,
},
fix(fixer): TSESLint.RuleFix | null {
return fixer.replaceTextRange(
[node.name.range[1], node.constraint.range[1]],
shouldAddTrailingComma() ? ',' : '',
);
},
},
],
});
}
};
return {
':not(ArrowFunctionExpression) > TSTypeParameterDeclaration > TSTypeParameter[constraint]'(
node: TypeParameterWithConstraint,
): void {
checkNode(node, false);
},
'ArrowFunctionExpression > TSTypeParameterDeclaration > TSTypeParameter[constraint]'(
node: TypeParameterWithConstraint,
): void {
checkNode(node, true);
},
};
}
Internal helpers¶
Declared inside another function in this file.
checkRequiresGenericDeclarationDisambiguation(filename: string): boolean¶
Parameters:
filenamestring
Returns: boolean
Calls:
extname(filename).toLocaleLowerCase
Code
checkNode(node: TypeParameterWithConstraint, inArrowFunction: boolean): void¶
Parameters:
nodeTypeParameterWithConstraintinArrowFunctionboolean
Returns: void
Calls:
unnecessaryConstraints.getcontext.sourceCode.getTokensAftercontext.reportfixer.replaceTextRangeshouldAddTrailingComma
Internal Comments:
Code
(
node: TypeParameterWithConstraint,
inArrowFunction: boolean,
): void => {
const constraint = unnecessaryConstraints.get(node.constraint.type);
function shouldAddTrailingComma(): boolean {
if (!inArrowFunction || !requiresGenericDeclarationDisambiguation) {
return false;
}
// Only <T>() => {} would need trailing comma
return (
(node.parent as TSESTree.TSTypeParameterDeclaration).params.length ===
1 &&
context.sourceCode.getTokensAfter(node)[0].value !== ',' &&
!node.default
);
}
if (constraint) {
context.report({
node,
messageId: 'unnecessaryConstraint',
data: {
name: node.name.name,
constraint,
},
suggest: [
{
messageId: 'removeUnnecessaryConstraint',
data: {
constraint,
},
fix(fixer): TSESLint.RuleFix | null {
return fixer.replaceTextRange(
[node.name.range[1], node.constraint.range[1]],
shouldAddTrailingComma() ? ',' : '',
);
},
},
],
});
}
}
shouldAddTrailingComma(): boolean¶
Returns: boolean
Calls:
context.sourceCode.getTokensAfter
Internal Comments:
Code
function shouldAddTrailingComma(): boolean {
if (!inArrowFunction || !requiresGenericDeclarationDisambiguation) {
return false;
}
// Only <T>() => {} would need trailing comma
return (
(node.parent as TSESTree.TSTypeParameterDeclaration).params.length ===
1 &&
context.sourceCode.getTokensAfter(node)[0].value !== ',' &&
!node.default
);
}
Type Aliases¶
TypeParameterWithConstraint¶
Generated by Syntax Scribe