Skip to content

Commit 28bc1cb

Browse files
committed
feat(require-template, check-template-names): add support FunctionDeclaration
1 parent 320a1eb commit 28bc1cb

File tree

8 files changed

+318
-7
lines changed

8 files changed

+318
-7
lines changed

.README/rules/check-template-names.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
Checks that any `@template` names are actually used in the connected
44
`@typedef` or type alias.
55

6-
Currently checks `TSInterfaceDeclaration` or `TSTypeAliasDeclaration` such as:
6+
Currently checks `FunctionDeclaration`, `TSInterfaceDeclaration` or
7+
`TSTypeAliasDeclaration` such as:
78

89
```ts
910
/**

.README/rules/require-template.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
Checks to see that `@template` tags are present for any detected type
44
parameters.
55

6-
Currently checks `TSInterfaceDeclaration` or `TSTypeAliasDeclaration` such as:
6+
Currently checks `FunctionDeclaration`, `TSInterfaceDeclaration` or
7+
`TSTypeAliasDeclaration` such as:
78

89
```ts
910
export type Pairs<D, V> = [D, V | undefined];

docs/rules/check-template-names.md

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
Checks that any `@template` names are actually used in the connected
66
`@typedef` or type alias.
77

8-
Currently checks `TSInterfaceDeclaration` or `TSTypeAliasDeclaration` such as:
8+
Currently checks `FunctionDeclaration`, `TSInterfaceDeclaration` or
9+
`TSTypeAliasDeclaration` such as:
910

1011
```ts
1112
/**
@@ -122,6 +123,33 @@ export default interface GenericIdentityFn<Type> {
122123
(arg: Type): Type;
123124
}
124125
// Message: @template D not in use
126+
127+
/**
128+
* @template D
129+
* @template V
130+
*/
131+
function identity<Type>(arg: Type): Type {
132+
return arg;
133+
}
134+
// Message: @template D not in use
135+
136+
/**
137+
* @template D
138+
* @template V
139+
*/
140+
export function identity<Type>(arg: Type): Type {
141+
return arg;
142+
}
143+
// Message: @template D not in use
144+
145+
/**
146+
* @template D
147+
* @template V
148+
*/
149+
export default function identity<Type>(arg: Type): Type {
150+
return arg;
151+
}
152+
// Message: @template D not in use
125153
````
126154

127155

@@ -194,5 +222,26 @@ export interface GenericIdentityFn<Type> {
194222
export default interface GenericIdentityFn<Type> {
195223
(arg: Type): Type;
196224
}
225+
226+
/**
227+
* @template Type
228+
*/
229+
function identity<Type>(arg: Type): Type {
230+
return arg;
231+
}
232+
233+
/**
234+
* @template Type
235+
*/
236+
export function identity<Type>(arg: Type): Type {
237+
return arg;
238+
}
239+
240+
/**
241+
* @template Type
242+
*/
243+
export default function identity<Type>(arg: Type): Type {
244+
return arg;
245+
}
197246
````
198247

docs/rules/require-template.md

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
Checks to see that `@template` tags are present for any detected type
66
parameters.
77

8-
Currently checks `TSInterfaceDeclaration` or `TSTypeAliasDeclaration` such as:
8+
Currently checks `FunctionDeclaration`, `TSInterfaceDeclaration` or
9+
`TSTypeAliasDeclaration` such as:
910

1011
```ts
1112
export type Pairs<D, V> = [D, V | undefined];
@@ -138,6 +139,30 @@ export default interface GenericIdentityFn<Type> {
138139
(arg: Type): Type;
139140
}
140141
// Message: Missing @template Type
142+
143+
/**
144+
*
145+
*/
146+
function identity<Type>(arg: Type): Type {
147+
return arg;
148+
}
149+
// Message: Missing @template Type
150+
151+
/**
152+
*
153+
*/
154+
export function identity<Type>(arg: Type): Type {
155+
return arg;
156+
}
157+
// Message: Missing @template Type
158+
159+
/**
160+
*
161+
*/
162+
export default function identity<Type>(arg: Type): Type {
163+
return arg;
164+
}
165+
// Message: Missing @template Type
141166
````
142167

143168

@@ -209,5 +234,26 @@ export interface GenericIdentityFn<Type> {
209234
export default interface GenericIdentityFn<Type> {
210235
(arg: Type): Type;
211236
}
237+
238+
/**
239+
* @template Type
240+
*/
241+
function identity<Type>(arg: Type): Type {
242+
return arg;
243+
}
244+
245+
/**
246+
* @template Type
247+
*/
248+
export function identity<Type>(arg: Type): Type {
249+
return arg;
250+
}
251+
252+
/**
253+
* @template Type
254+
*/
255+
export default function identity<Type>(arg: Type): Type {
256+
return arg;
257+
}
212258
````
213259

src/rules/checkTemplateNames.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ export default iterateJsdoc(({
2020

2121
const usedNames = new Set();
2222
/**
23-
* @param {import('@typescript-eslint/types').TSESTree.TSInterfaceDeclaration|
23+
* @param {import('@typescript-eslint/types').TSESTree.FunctionDeclaration|
24+
* import('@typescript-eslint/types').TSESTree.TSInterfaceDeclaration|
2425
* import('@typescript-eslint/types').TSESTree.TSTypeAliasDeclaration} aliasDeclaration
2526
*/
2627
const checkParameters = (aliasDeclaration) => {
@@ -51,12 +52,14 @@ export default iterateJsdoc(({
5152
case 'ExportDefaultDeclaration':
5253
case 'ExportNamedDeclaration':
5354
switch (nde.declaration?.type) {
55+
case 'FunctionDeclaration':
5456
case 'TSTypeAliasDeclaration':
5557
case 'TSInterfaceDeclaration':
56-
checkParameters(nde.declaration);
58+
checkParameters(nde.declaration);
5759
break;
5860
}
5961
break;
62+
case 'FunctionDeclaration':
6063
case 'TSTypeAliasDeclaration':
6164
case 'TSInterfaceDeclaration':
6265
checkParameters(nde);

src/rules/requireTemplate.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ export default iterateJsdoc(({
3535
}
3636

3737
/**
38-
* @param {import('@typescript-eslint/types').TSESTree.TSInterfaceDeclaration|
38+
* @param {import('@typescript-eslint/types').TSESTree.FunctionDeclaration|
39+
* import('@typescript-eslint/types').TSESTree.TSInterfaceDeclaration|
3940
* import('@typescript-eslint/types').TSESTree.TSTypeAliasDeclaration} aliasDeclaration
4041
*/
4142
const checkTypeParams = (aliasDeclaration) => {
@@ -61,19 +62,22 @@ export default iterateJsdoc(({
6162
switch (nde.type) {
6263
case 'ExportDefaultDeclaration':
6364
switch (nde.declaration?.type) {
65+
case 'FunctionDeclaration':
6466
case 'TSInterfaceDeclaration':
6567
checkTypeParams(nde.declaration);
6668
break;
6769
}
6870
break;
6971
case 'ExportNamedDeclaration':
7072
switch (nde.declaration?.type) {
73+
case 'FunctionDeclaration':
7174
case 'TSTypeAliasDeclaration':
7275
case 'TSInterfaceDeclaration':
7376
checkTypeParams(nde.declaration);
7477
break;
7578
}
7679
break;
80+
case 'FunctionDeclaration':
7781
case 'TSTypeAliasDeclaration':
7882
case 'TSInterfaceDeclaration':
7983
checkTypeParams(nde);

test/rules/assertions/checkTemplateNames.js

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,78 @@ export default {
230230
parser: typescriptEslintParser
231231
},
232232
},
233+
{
234+
code: `
235+
/**
236+
* @template D
237+
* @template V
238+
*/
239+
function identity<Type>(arg: Type): Type {
240+
return arg;
241+
}
242+
`,
243+
errors: [
244+
{
245+
line: 3,
246+
message: '@template D not in use',
247+
},
248+
{
249+
line: 4,
250+
message: '@template V not in use',
251+
},
252+
],
253+
languageOptions: {
254+
parser: typescriptEslintParser
255+
},
256+
},
257+
{
258+
code: `
259+
/**
260+
* @template D
261+
* @template V
262+
*/
263+
export function identity<Type>(arg: Type): Type {
264+
return arg;
265+
}
266+
`,
267+
errors: [
268+
{
269+
line: 3,
270+
message: '@template D not in use',
271+
},
272+
{
273+
line: 4,
274+
message: '@template V not in use',
275+
},
276+
],
277+
languageOptions: {
278+
parser: typescriptEslintParser
279+
},
280+
},
281+
{
282+
code: `
283+
/**
284+
* @template D
285+
* @template V
286+
*/
287+
export default function identity<Type>(arg: Type): Type {
288+
return arg;
289+
}
290+
`,
291+
errors: [
292+
{
293+
line: 3,
294+
message: '@template D not in use',
295+
},
296+
{
297+
line: 4,
298+
message: '@template V not in use',
299+
},
300+
],
301+
languageOptions: {
302+
parser: typescriptEslintParser
303+
},
304+
},
233305
],
234306
valid: [
235307
{
@@ -339,5 +411,44 @@ export default {
339411
parser: typescriptEslintParser
340412
},
341413
},
414+
{
415+
code: `
416+
/**
417+
* @template Type
418+
*/
419+
function identity<Type>(arg: Type): Type {
420+
return arg;
421+
}
422+
`,
423+
languageOptions: {
424+
parser: typescriptEslintParser
425+
},
426+
},
427+
{
428+
code: `
429+
/**
430+
* @template Type
431+
*/
432+
export function identity<Type>(arg: Type): Type {
433+
return arg;
434+
}
435+
`,
436+
languageOptions: {
437+
parser: typescriptEslintParser
438+
},
439+
},
440+
{
441+
code: `
442+
/**
443+
* @template Type
444+
*/
445+
export default function identity<Type>(arg: Type): Type {
446+
return arg;
447+
}
448+
`,
449+
languageOptions: {
450+
parser: typescriptEslintParser
451+
},
452+
},
342453
],
343454
};

0 commit comments

Comments
 (0)