diff --git a/.README/rules/check-template-names.md b/.README/rules/check-template-names.md index 51e0f377..6c8b4fa3 100644 --- a/.README/rules/check-template-names.md +++ b/.README/rules/check-template-names.md @@ -3,7 +3,8 @@ Checks that any `@template` names are actually used in the connected `@typedef` or type alias. -Currently checks `TSInterfaceDeclaration` or `TSTypeAliasDeclaration` such as: +Currently checks `FunctionDeclaration`, `TSInterfaceDeclaration` or +`TSTypeAliasDeclaration` such as: ```ts /** diff --git a/.README/rules/require-template.md b/.README/rules/require-template.md index 2544f1d9..e8ca4577 100644 --- a/.README/rules/require-template.md +++ b/.README/rules/require-template.md @@ -3,7 +3,8 @@ Checks to see that `@template` tags are present for any detected type parameters. -Currently checks `TSInterfaceDeclaration` or `TSTypeAliasDeclaration` such as: +Currently checks `FunctionDeclaration`, `TSInterfaceDeclaration` or +`TSTypeAliasDeclaration` such as: ```ts export type Pairs = [D, V | undefined]; diff --git a/docs/rules/check-template-names.md b/docs/rules/check-template-names.md index 7249f041..091ae178 100644 --- a/docs/rules/check-template-names.md +++ b/docs/rules/check-template-names.md @@ -5,7 +5,8 @@ Checks that any `@template` names are actually used in the connected `@typedef` or type alias. -Currently checks `TSInterfaceDeclaration` or `TSTypeAliasDeclaration` such as: +Currently checks `FunctionDeclaration`, `TSInterfaceDeclaration` or +`TSTypeAliasDeclaration` such as: ```ts /** @@ -122,6 +123,33 @@ export default interface GenericIdentityFn { (arg: Type): Type; } // Message: @template D not in use + +/** + * @template D + * @template V + */ +function identity(arg: Type): Type { + return arg; +} +// Message: @template D not in use + +/** + * @template D + * @template V + */ +export function identity(arg: Type): Type { + return arg; +} +// Message: @template D not in use + +/** + * @template D + * @template V + */ +export default function identity(arg: Type): Type { + return arg; +} +// Message: @template D not in use ```` @@ -194,5 +222,26 @@ export interface GenericIdentityFn { export default interface GenericIdentityFn { (arg: Type): Type; } + +/** + * @template Type + */ +function identity(arg: Type): Type { + return arg; +} + +/** + * @template Type + */ +export function identity(arg: Type): Type { + return arg; +} + +/** + * @template Type + */ +export default function identity(arg: Type): Type { + return arg; +} ```` diff --git a/docs/rules/require-template.md b/docs/rules/require-template.md index 16d8e3f0..b9109c09 100644 --- a/docs/rules/require-template.md +++ b/docs/rules/require-template.md @@ -5,7 +5,8 @@ Checks to see that `@template` tags are present for any detected type parameters. -Currently checks `TSInterfaceDeclaration` or `TSTypeAliasDeclaration` such as: +Currently checks `FunctionDeclaration`, `TSInterfaceDeclaration` or +`TSTypeAliasDeclaration` such as: ```ts export type Pairs = [D, V | undefined]; @@ -138,6 +139,30 @@ export default interface GenericIdentityFn { (arg: Type): Type; } // Message: Missing @template Type + +/** + * + */ +function identity(arg: Type): Type { + return arg; +} +// Message: Missing @template Type + +/** + * + */ +export function identity(arg: Type): Type { + return arg; +} +// Message: Missing @template Type + +/** + * + */ +export default function identity(arg: Type): Type { + return arg; +} +// Message: Missing @template Type ```` @@ -209,5 +234,26 @@ export interface GenericIdentityFn { export default interface GenericIdentityFn { (arg: Type): Type; } + +/** + * @template Type + */ +function identity(arg: Type): Type { + return arg; +} + +/** + * @template Type + */ +export function identity(arg: Type): Type { + return arg; +} + +/** + * @template Type + */ +export default function identity(arg: Type): Type { + return arg; +} ```` diff --git a/src/rules/checkTemplateNames.js b/src/rules/checkTemplateNames.js index 9a2914eb..57ecd810 100644 --- a/src/rules/checkTemplateNames.js +++ b/src/rules/checkTemplateNames.js @@ -20,7 +20,8 @@ export default iterateJsdoc(({ const usedNames = new Set(); /** - * @param {import('@typescript-eslint/types').TSESTree.TSInterfaceDeclaration| + * @param {import('@typescript-eslint/types').TSESTree.FunctionDeclaration| + * import('@typescript-eslint/types').TSESTree.TSInterfaceDeclaration| * import('@typescript-eslint/types').TSESTree.TSTypeAliasDeclaration} aliasDeclaration */ const checkParameters = (aliasDeclaration) => { @@ -51,12 +52,14 @@ export default iterateJsdoc(({ case 'ExportDefaultDeclaration': case 'ExportNamedDeclaration': switch (nde.declaration?.type) { + case 'FunctionDeclaration': case 'TSTypeAliasDeclaration': case 'TSInterfaceDeclaration': - checkParameters(nde.declaration); + checkParameters(nde.declaration); break; } break; + case 'FunctionDeclaration': case 'TSTypeAliasDeclaration': case 'TSInterfaceDeclaration': checkParameters(nde); diff --git a/src/rules/requireTemplate.js b/src/rules/requireTemplate.js index ebee54a0..c06da7ed 100644 --- a/src/rules/requireTemplate.js +++ b/src/rules/requireTemplate.js @@ -35,7 +35,8 @@ export default iterateJsdoc(({ } /** - * @param {import('@typescript-eslint/types').TSESTree.TSInterfaceDeclaration| + * @param {import('@typescript-eslint/types').TSESTree.FunctionDeclaration| + * import('@typescript-eslint/types').TSESTree.TSInterfaceDeclaration| * import('@typescript-eslint/types').TSESTree.TSTypeAliasDeclaration} aliasDeclaration */ const checkTypeParams = (aliasDeclaration) => { @@ -61,6 +62,7 @@ export default iterateJsdoc(({ switch (nde.type) { case 'ExportDefaultDeclaration': switch (nde.declaration?.type) { + case 'FunctionDeclaration': case 'TSInterfaceDeclaration': checkTypeParams(nde.declaration); break; @@ -68,12 +70,14 @@ export default iterateJsdoc(({ break; case 'ExportNamedDeclaration': switch (nde.declaration?.type) { + case 'FunctionDeclaration': case 'TSTypeAliasDeclaration': case 'TSInterfaceDeclaration': checkTypeParams(nde.declaration); break; } break; + case 'FunctionDeclaration': case 'TSTypeAliasDeclaration': case 'TSInterfaceDeclaration': checkTypeParams(nde); diff --git a/test/rules/assertions/checkTemplateNames.js b/test/rules/assertions/checkTemplateNames.js index 254a34f0..91471bc9 100644 --- a/test/rules/assertions/checkTemplateNames.js +++ b/test/rules/assertions/checkTemplateNames.js @@ -230,6 +230,78 @@ export default { parser: typescriptEslintParser }, }, + { + code: ` + /** + * @template D + * @template V + */ + function identity(arg: Type): Type { + return arg; + } + `, + errors: [ + { + line: 3, + message: '@template D not in use', + }, + { + line: 4, + message: '@template V not in use', + }, + ], + languageOptions: { + parser: typescriptEslintParser + }, + }, + { + code: ` + /** + * @template D + * @template V + */ + export function identity(arg: Type): Type { + return arg; + } + `, + errors: [ + { + line: 3, + message: '@template D not in use', + }, + { + line: 4, + message: '@template V not in use', + }, + ], + languageOptions: { + parser: typescriptEslintParser + }, + }, + { + code: ` + /** + * @template D + * @template V + */ + export default function identity(arg: Type): Type { + return arg; + } + `, + errors: [ + { + line: 3, + message: '@template D not in use', + }, + { + line: 4, + message: '@template V not in use', + }, + ], + languageOptions: { + parser: typescriptEslintParser + }, + }, ], valid: [ { @@ -339,5 +411,44 @@ export default { parser: typescriptEslintParser }, }, + { + code: ` + /** + * @template Type + */ + function identity(arg: Type): Type { + return arg; + } + `, + languageOptions: { + parser: typescriptEslintParser + }, + }, + { + code: ` + /** + * @template Type + */ + export function identity(arg: Type): Type { + return arg; + } + `, + languageOptions: { + parser: typescriptEslintParser + }, + }, + { + code: ` + /** + * @template Type + */ + export default function identity(arg: Type): Type { + return arg; + } + `, + languageOptions: { + parser: typescriptEslintParser + }, + }, ], }; diff --git a/test/rules/assertions/requireTemplate.js b/test/rules/assertions/requireTemplate.js index 75677199..8ad9e530 100644 --- a/test/rules/assertions/requireTemplate.js +++ b/test/rules/assertions/requireTemplate.js @@ -228,6 +228,63 @@ export default { parser: typescriptEslintParser }, }, + { + code: ` + /** + * + */ + function identity(arg: Type): Type { + return arg; + } + `, + errors: [ + { + line: 2, + message: 'Missing @template Type', + }, + ], + languageOptions: { + parser: typescriptEslintParser + }, + }, + { + code: ` + /** + * + */ + export function identity(arg: Type): Type { + return arg; + } + `, + errors: [ + { + line: 2, + message: 'Missing @template Type', + }, + ], + languageOptions: { + parser: typescriptEslintParser + }, + }, + { + code: ` + /** + * + */ + export default function identity(arg: Type): Type { + return arg; + } + `, + errors: [ + { + line: 2, + message: 'Missing @template Type', + }, + ], + languageOptions: { + parser: typescriptEslintParser + }, + }, ], valid: [ { @@ -336,5 +393,44 @@ export default { parser: typescriptEslintParser }, }, + { + code: ` + /** + * @template Type + */ + function identity(arg: Type): Type { + return arg; + } + `, + languageOptions: { + parser: typescriptEslintParser + }, + }, + { + code: ` + /** + * @template Type + */ + export function identity(arg: Type): Type { + return arg; + } + `, + languageOptions: { + parser: typescriptEslintParser + }, + }, + { + code: ` + /** + * @template Type + */ + export default function identity(arg: Type): Type { + return arg; + } + `, + languageOptions: { + parser: typescriptEslintParser + }, + }, ], };