diff --git a/.README/rules/check-template-names.md b/.README/rules/check-template-names.md
index 34aaef77..64492c09 100644
--- a/.README/rules/check-template-names.md
+++ b/.README/rules/check-template-names.md
@@ -1,7 +1,7 @@
# `check-template-names`
Checks that any `@template` names are actually used in the connected
-`@typedef` or type alias.
+`@typedef`, `@callback`, `@function` or type structure.
Currently checks `ClassDeclaration`, `FunctionDeclaration`,
`TSInterfaceDeclaration` or `TSTypeAliasDeclaration` such as:
diff --git a/docs/rules/check-template-names.md b/docs/rules/check-template-names.md
index 996895d0..f7ce1ca0 100644
--- a/docs/rules/check-template-names.md
+++ b/docs/rules/check-template-names.md
@@ -3,7 +3,7 @@
# check-template-names
Checks that any `@template` names are actually used in the connected
-`@typedef` or type alias.
+`@typedef`, `@callback`, `@function` or type structure.
Currently checks `ClassDeclaration`, `FunctionDeclaration`,
`TSInterfaceDeclaration` or `TSTypeAliasDeclaration` such as:
@@ -190,6 +190,30 @@ export default class {
add: (x: NumType, y: NumType) => NumType;
}
// Message: @template D not in use
+
+/**
+ * @template D
+ * @template V
+ * @callback
+ * @returns {[X, Y | undefined]}
+ */
+// Message: @template D not in use
+
+/**
+ * @template D
+ * @template V
+ * @function
+ * @returns {[X, Y | undefined]}
+ */
+// Message: @template D not in use
+
+/**
+ * @template D
+ * @template V
+ * @function
+ * @param {[X, Y | undefined]} someParam
+ */
+// Message: @template D not in use
````
@@ -327,5 +351,26 @@ export default class {
*/
export function mapGroupBy(array, callbackFn) {
}
+
+/**
+ * @template D
+ * @template V
+ * @callback
+ * @returns {[D, V | undefined]}
+ */
+
+/**
+ * @template D
+ * @template V
+ * @function
+ * @returns {[D, V | undefined]}
+ */
+
+/**
+ * @template D
+ * @template V
+ * @function
+ * @param {[D, V | undefined]} someParam
+ */
````
diff --git a/src/rules/checkTemplateNames.js b/src/rules/checkTemplateNames.js
index 28b2c180..df38316b 100644
--- a/src/rules/checkTemplateNames.js
+++ b/src/rules/checkTemplateNames.js
@@ -43,6 +43,36 @@ export default iterateJsdoc(({
});
};
+ const checkParamsAndReturnsTags = () => {
+ const paramName = /** @type {string} */ (utils.getPreferredTagName({
+ tagName: 'param',
+ }));
+ const paramTags = utils.getTags(paramName);
+ for (const paramTag of paramTags) {
+ checkForUsedTypes(paramTag.type);
+ }
+
+ const returnsName = /** @type {string} */ (utils.getPreferredTagName({
+ tagName: 'returns',
+ }));
+ const returnsTags = utils.getTags(returnsName);
+ for (const returnsTag of returnsTags) {
+ checkForUsedTypes(returnsTag.type);
+ }
+ };
+
+ const checkTemplateTags = () => {
+ for (const tag of templateTags) {
+ const {name} = tag;
+ const names = name.split(/,\s*/);
+ for (const name of names) {
+ if (!usedNames.has(name)) {
+ report(`@template ${name} not in use`, null, tag);
+ }
+ }
+ }
+ };
+
/**
* @param {import('@typescript-eslint/types').TSESTree.FunctionDeclaration|
* import('@typescript-eslint/types').TSESTree.ClassDeclaration|
@@ -57,31 +87,10 @@ export default iterateJsdoc(({
usedNames.add(name);
}
if (checkParamsAndReturns) {
- const paramName = /** @type {string} */ (utils.getPreferredTagName({
- tagName: 'param',
- }));
- const paramTags = utils.getTags(paramName);
- for (const paramTag of paramTags) {
- checkForUsedTypes(paramTag.type);
- }
-
- const returnsName = /** @type {string} */ (utils.getPreferredTagName({
- tagName: 'returns',
- }));
- const returnsTags = utils.getTags(returnsName);
- for (const returnsTag of returnsTags) {
- checkForUsedTypes(returnsTag.type);
- }
- }
- for (const tag of templateTags) {
- const {name} = tag;
- const names = name.split(/,\s*/);
- for (const name of names) {
- if (!usedNames.has(name)) {
- report(`@template ${name} not in use`, null, tag);
- }
- }
+ checkParamsAndReturnsTags();
}
+
+ checkTemplateTags();
};
const handleTypeAliases = () => {
@@ -116,6 +125,14 @@ export default iterateJsdoc(({
}
};
+ const callbackTags = utils.getTags('callback');
+ const functionTags = utils.getTags('function');
+ if (callbackTags.length || functionTags.length) {
+ checkParamsAndReturnsTags();
+ checkTemplateTags();
+ return;
+ }
+
const typedefTags = utils.getTags('typedef');
if (!typedefTags.length || typedefTags.length >= 2) {
handleTypeAliases();
diff --git a/test/rules/assertions/checkTemplateNames.js b/test/rules/assertions/checkTemplateNames.js
index 639448ad..98dc1827 100644
--- a/test/rules/assertions/checkTemplateNames.js
+++ b/test/rules/assertions/checkTemplateNames.js
@@ -402,6 +402,66 @@ export default {
parser: typescriptEslintParser
},
},
+ {
+ code: `
+ /**
+ * @template D
+ * @template V
+ * @callback
+ * @returns {[X, Y | undefined]}
+ */
+ `,
+ errors: [
+ {
+ line: 3,
+ message: '@template D not in use',
+ },
+ {
+ line: 4,
+ message: '@template V not in use',
+ },
+ ],
+ },
+ {
+ code: `
+ /**
+ * @template D
+ * @template V
+ * @function
+ * @returns {[X, Y | undefined]}
+ */
+ `,
+ errors: [
+ {
+ line: 3,
+ message: '@template D not in use',
+ },
+ {
+ line: 4,
+ message: '@template V not in use',
+ },
+ ],
+ },
+ {
+ code: `
+ /**
+ * @template D
+ * @template V
+ * @function
+ * @param {[X, Y | undefined]} someParam
+ */
+ `,
+ errors: [
+ {
+ line: 3,
+ message: '@template D not in use',
+ },
+ {
+ line: 4,
+ message: '@template V not in use',
+ },
+ ],
+ },
],
valid: [
{
@@ -624,5 +684,35 @@ export default {
parser: typescriptEslintParser
},
},
+ {
+ code: `
+ /**
+ * @template D
+ * @template V
+ * @callback
+ * @returns {[D, V | undefined]}
+ */
+ `,
+ },
+ {
+ code: `
+ /**
+ * @template D
+ * @template V
+ * @function
+ * @returns {[D, V | undefined]}
+ */
+ `,
+ },
+ {
+ code: `
+ /**
+ * @template D
+ * @template V
+ * @function
+ * @param {[D, V | undefined]} someParam
+ */
+ `,
+ },
],
};