eslint-plugin-jsdoc 57.2.0 → 58.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/rules.d.ts CHANGED
@@ -1,4 +1,7 @@
1
1
  export interface Rules {
2
+ /** Checks that `@access` tags have a valid value. */
3
+ "jsdoc/check-access": [];
4
+
2
5
  /** Reports invalid alignment of JSDoc block asterisks. */
3
6
  "jsdoc/check-alignment":
4
7
  | []
@@ -90,6 +93,9 @@ export interface Rules {
90
93
  }
91
94
  ];
92
95
 
96
+ /** Reports against syntax not valid for the mode (e.g., Google Closure Compiler in non-Closure mode). */
97
+ "jsdoc/check-syntax": [];
98
+
93
99
  /** Reports invalid block tag names. */
94
100
  "jsdoc/check-tag-names":
95
101
  | []
@@ -102,6 +108,9 @@ export interface Rules {
102
108
  }
103
109
  ];
104
110
 
111
+ /** Checks that any `@template` names are actually used in the connected `@typedef` or type alias. */
112
+ "jsdoc/check-template-names": [];
113
+
105
114
  /** Reports invalid types. */
106
115
  "jsdoc/check-types":
107
116
  | []
@@ -188,6 +197,9 @@ export interface Rules {
188
197
  }
189
198
  ];
190
199
 
200
+ /** Reports if JSDoc `import()` statements point to a package which is not listed in `dependencies` or `devDependencies` */
201
+ "jsdoc/imports-as-dependencies": [];
202
+
191
203
  /** This rule reports doc comments that only restate their attached name. */
192
204
  "jsdoc/informative-docs":
193
205
  | []
@@ -300,6 +312,9 @@ export interface Rules {
300
312
  }
301
313
  ];
302
314
 
315
+ /** Detects and removes extra lines of a blank block description */
316
+ "jsdoc/no-blank-block-descriptions": [];
317
+
303
318
  /** Removes empty blocks with nothing but possibly line breaks */
304
319
  "jsdoc/no-blank-blocks":
305
320
  | []
@@ -395,6 +410,12 @@ export interface Rules {
395
410
  }
396
411
  ];
397
412
 
413
+ /** Reports use of `any` or `*` type */
414
+ "jsdoc/reject-any-type": [];
415
+
416
+ /** Reports use of `Function` type */
417
+ "jsdoc/reject-function-type": [];
418
+
398
419
  /** Requires that each JSDoc line starts with an `*`. */
399
420
  "jsdoc/require-asterisk-prefix":
400
421
  | []
@@ -542,6 +563,9 @@ export interface Rules {
542
563
  }
543
564
  ];
544
565
 
566
+ /** Requires a type for `@next` tags */
567
+ "jsdoc/require-next-type": [];
568
+
545
569
  /** Requires that all function parameters are documented. */
546
570
  "jsdoc/require-param":
547
571
  | []
@@ -621,6 +645,18 @@ export interface Rules {
621
645
  }
622
646
  ];
623
647
 
648
+ /** Requires that all `@typedef` and `@namespace` tags have `@property` when their type is a plain `object`, `Object`, or `PlainObject`. */
649
+ "jsdoc/require-property": [];
650
+
651
+ /** Requires that each `@property` tag has a `description` value. */
652
+ "jsdoc/require-property-description": [];
653
+
654
+ /** Requires that all function `@property` tags have names. */
655
+ "jsdoc/require-property-name": [];
656
+
657
+ /** Requires that each `@property` tag has a `type` value. */
658
+ "jsdoc/require-property-type": [];
659
+
624
660
  /** Requires that returns are documented. */
625
661
  "jsdoc/require-returns":
626
662
  | []
@@ -718,6 +754,9 @@ export interface Rules {
718
754
  }
719
755
  ];
720
756
 
757
+ /** Requires a type for `@throws` tags */
758
+ "jsdoc/require-throws-type": [];
759
+
721
760
  /** Requires yields are documented. */
722
761
  "jsdoc/require-yields":
723
762
  | []
@@ -757,6 +796,9 @@ export interface Rules {
757
796
  }
758
797
  ];
759
798
 
799
+ /** Requires a type for `@yields` tags */
800
+ "jsdoc/require-yields-type": [];
801
+
760
802
  /** Sorts tags by a specified sequence according to tag name. */
761
803
  "jsdoc/sort-tags":
762
804
  | []
package/package.json CHANGED
@@ -172,5 +172,5 @@
172
172
  "test-cov": "TIMING=1 c8 --reporter text pnpm run test-no-cov",
173
173
  "test-index": "pnpm run test-no-cov test/rules/index.js"
174
174
  },
175
- "version": "57.2.0"
175
+ "version": "58.0.0"
176
176
  }
@@ -0,0 +1,472 @@
1
+ import iterateJsdoc from './iterateJsdoc.js';
2
+ import {
3
+ parse,
4
+ stringify,
5
+ traverse,
6
+ tryParse,
7
+ } from '@es-joy/jsdoccomment';
8
+
9
+ /**
10
+ * Adjusts the parent type node `meta` for generic matches (or type node
11
+ * `type` for `JsdocTypeAny`) and sets the type node `value`.
12
+ * @param {string} type The actual type
13
+ * @param {string} preferred The preferred type
14
+ * @param {boolean} isGenericMatch
15
+ * @param {string} typeNodeName
16
+ * @param {import('jsdoc-type-pratt-parser').NonRootResult} node
17
+ * @param {import('jsdoc-type-pratt-parser').NonRootResult|undefined} parentNode
18
+ * @returns {void}
19
+ */
20
+ const adjustNames = (type, preferred, isGenericMatch, typeNodeName, node, parentNode) => {
21
+ let ret = preferred;
22
+ if (isGenericMatch) {
23
+ const parentMeta = /** @type {import('jsdoc-type-pratt-parser').GenericResult} */ (
24
+ parentNode
25
+ ).meta;
26
+ if (preferred === '[]') {
27
+ parentMeta.brackets = 'square';
28
+ parentMeta.dot = false;
29
+ ret = 'Array';
30
+ } else {
31
+ const dotBracketEnd = preferred.match(/\.(?:<>)?$/v);
32
+ if (dotBracketEnd) {
33
+ parentMeta.brackets = 'angle';
34
+ parentMeta.dot = true;
35
+ ret = preferred.slice(0, -dotBracketEnd[0].length);
36
+ } else {
37
+ const bracketEnd = preferred.endsWith('<>');
38
+ if (bracketEnd) {
39
+ parentMeta.brackets = 'angle';
40
+ parentMeta.dot = false;
41
+ ret = preferred.slice(0, -2);
42
+ } else if (
43
+ parentMeta?.brackets === 'square' &&
44
+ (typeNodeName === '[]' || typeNodeName === 'Array')
45
+ ) {
46
+ parentMeta.brackets = 'angle';
47
+ parentMeta.dot = false;
48
+ }
49
+ }
50
+ }
51
+ } else if (type === 'JsdocTypeAny') {
52
+ node.type = 'JsdocTypeName';
53
+ }
54
+
55
+ /** @type {import('jsdoc-type-pratt-parser').NameResult} */ (
56
+ node
57
+ ).value = ret.replace(/(?:\.|<>|\.<>|\[\])$/v, '');
58
+
59
+ // For bare pseudo-types like `<>`
60
+ if (!ret) {
61
+ /** @type {import('jsdoc-type-pratt-parser').NameResult} */ (
62
+ node
63
+ ).value = typeNodeName;
64
+ }
65
+ };
66
+
67
+ /**
68
+ * @param {boolean} [upperCase]
69
+ * @returns {string}
70
+ */
71
+ const getMessage = (upperCase) => {
72
+ return 'Use object shorthand or index signatures instead of ' +
73
+ '`' + (upperCase ? 'O' : 'o') + 'bject`, e.g., `{[key: string]: string}`';
74
+ };
75
+
76
+ /**
77
+ * @type {{
78
+ * message: string,
79
+ * replacement: false
80
+ * }}
81
+ */
82
+ const info = {
83
+ message: getMessage(),
84
+ replacement: false,
85
+ };
86
+
87
+ /**
88
+ * @type {{
89
+ * message: string,
90
+ * replacement: false
91
+ * }}
92
+ */
93
+ const infoUC = {
94
+ message: getMessage(true),
95
+ replacement: false,
96
+ };
97
+
98
+ /**
99
+ * @param {{
100
+ * checkNativeTypes?: import('./rules/checkTypes.js').CheckNativeTypes|null
101
+ * overrideSettings?: import('./iterateJsdoc.js').Settings['preferredTypes']|null,
102
+ * description?: string,
103
+ * schema?: import('eslint').Rule.RuleMetaData['schema'],
104
+ * typeName?: string,
105
+ * url?: string,
106
+ * }} cfg
107
+ * @returns {import('@eslint/core').RuleDefinition<
108
+ * import('@eslint/core').RuleDefinitionTypeOptions
109
+ * >}
110
+ */
111
+ export const buildRejectOrPreferRuleDefinition = ({
112
+ checkNativeTypes = null,
113
+ typeName,
114
+ description = typeName ?? 'Reports invalid types.',
115
+ overrideSettings = null,
116
+ schema = [],
117
+ url = 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/check-types.md#repos-sticky-header',
118
+ }) => {
119
+ return iterateJsdoc(
120
+ ({
121
+ context,
122
+ jsdocNode,
123
+ report,
124
+ settings,
125
+ sourceCode,
126
+ utils,
127
+ }) => {
128
+ const jsdocTagsWithPossibleType = utils.filterTags((tag) => {
129
+ return Boolean(utils.tagMightHaveTypePosition(tag.tag));
130
+ });
131
+
132
+ const
133
+ /**
134
+ * @type {{
135
+ * preferredTypes: import('./iterateJsdoc.js').PreferredTypes,
136
+ * structuredTags: import('./iterateJsdoc.js').StructuredTags,
137
+ * mode: import('./jsdocUtils.js').ParserMode
138
+ * }}
139
+ */
140
+ {
141
+ mode,
142
+ preferredTypes: preferredTypesOriginal,
143
+ structuredTags,
144
+ } = overrideSettings ? {
145
+ mode: settings.mode,
146
+ preferredTypes: overrideSettings,
147
+ structuredTags: {},
148
+ } : settings;
149
+
150
+ const injectObjectPreferredTypes = !('Object' in preferredTypesOriginal ||
151
+ 'object' in preferredTypesOriginal ||
152
+ 'object.<>' in preferredTypesOriginal ||
153
+ 'Object.<>' in preferredTypesOriginal ||
154
+ 'object<>' in preferredTypesOriginal);
155
+
156
+ /** @type {import('./iterateJsdoc.js').PreferredTypes} */
157
+ const typeToInject = mode === 'typescript' ?
158
+ {
159
+ Object: 'object',
160
+ 'object.<>': info,
161
+ 'Object.<>': infoUC,
162
+ 'object<>': info,
163
+ 'Object<>': infoUC,
164
+ } :
165
+ {
166
+ Object: 'object',
167
+ 'object.<>': 'Object<>',
168
+ 'Object.<>': 'Object<>',
169
+ 'object<>': 'Object<>',
170
+ };
171
+
172
+ /** @type {import('./iterateJsdoc.js').PreferredTypes} */
173
+ const preferredTypes = {
174
+ ...injectObjectPreferredTypes ?
175
+ typeToInject :
176
+ {},
177
+ ...preferredTypesOriginal,
178
+ };
179
+
180
+ const
181
+ /**
182
+ * @type {{
183
+ * noDefaults: boolean,
184
+ * unifyParentAndChildTypeChecks: boolean,
185
+ * exemptTagContexts: ({
186
+ * tag: string,
187
+ * types: true|string[]
188
+ * })[]
189
+ * }}
190
+ */ {
191
+ exemptTagContexts = [],
192
+ noDefaults,
193
+ unifyParentAndChildTypeChecks,
194
+ } = context.options[0] || {};
195
+
196
+ /**
197
+ * Gets information about the preferred type: whether there is a matching
198
+ * preferred type, what the type is, and whether it is a match to a generic.
199
+ * @param {string} _type Not currently in use
200
+ * @param {string} typeNodeName
201
+ * @param {import('jsdoc-type-pratt-parser').NonRootResult|undefined} parentNode
202
+ * @param {string|undefined} property
203
+ * @returns {[hasMatchingPreferredType: boolean, typeName: string, isGenericMatch: boolean]}
204
+ */
205
+ const getPreferredTypeInfo = (_type, typeNodeName, parentNode, property) => {
206
+ let hasMatchingPreferredType = false;
207
+ let isGenericMatch = false;
208
+ let typName = typeNodeName;
209
+
210
+ const isNameOfGeneric = parentNode !== undefined && parentNode.type === 'JsdocTypeGeneric' && property === 'left';
211
+
212
+ const brackets = /** @type {import('jsdoc-type-pratt-parser').GenericResult} */ (
213
+ parentNode
214
+ )?.meta?.brackets;
215
+ const dot = /** @type {import('jsdoc-type-pratt-parser').GenericResult} */ (
216
+ parentNode
217
+ )?.meta?.dot;
218
+
219
+ if (brackets === 'angle') {
220
+ const checkPostFixes = dot ? [
221
+ '.', '.<>',
222
+ ] : [
223
+ '<>',
224
+ ];
225
+ isGenericMatch = checkPostFixes.some((checkPostFix) => {
226
+ const preferredType = preferredTypes?.[typeNodeName + checkPostFix];
227
+
228
+ // Does `unifyParentAndChildTypeChecks` need to be checked here?
229
+ if (
230
+ (unifyParentAndChildTypeChecks || isNameOfGeneric ||
231
+ /* c8 ignore next 2 -- If checking `unifyParentAndChildTypeChecks` */
232
+ (typeof preferredType === 'object' &&
233
+ preferredType?.unifyParentAndChildTypeChecks)
234
+ ) &&
235
+ preferredType !== undefined
236
+ ) {
237
+ typName += checkPostFix;
238
+
239
+ return true;
240
+ }
241
+
242
+ return false;
243
+ });
244
+ }
245
+
246
+ if (
247
+ !isGenericMatch && property &&
248
+ /** @type {import('jsdoc-type-pratt-parser').NonRootResult} */ (
249
+ parentNode
250
+ ).type === 'JsdocTypeGeneric'
251
+ ) {
252
+ const checkPostFixes = dot ? [
253
+ '.', '.<>',
254
+ ] : [
255
+ brackets === 'angle' ? '<>' : '[]',
256
+ ];
257
+
258
+ isGenericMatch = checkPostFixes.some((checkPostFix) => {
259
+ const preferredType = preferredTypes?.[checkPostFix];
260
+ if (
261
+ // Does `unifyParentAndChildTypeChecks` need to be checked here?
262
+ (unifyParentAndChildTypeChecks || isNameOfGeneric ||
263
+ /* c8 ignore next 2 -- If checking `unifyParentAndChildTypeChecks` */
264
+ (typeof preferredType === 'object' &&
265
+ preferredType?.unifyParentAndChildTypeChecks)) &&
266
+ preferredType !== undefined
267
+ ) {
268
+ typName = checkPostFix;
269
+
270
+ return true;
271
+ }
272
+
273
+ return false;
274
+ });
275
+ }
276
+
277
+ const prefType = preferredTypes?.[typeNodeName];
278
+ const directNameMatch = prefType !== undefined &&
279
+ !Object.values(preferredTypes).includes(typeNodeName);
280
+ const specificUnify = typeof prefType === 'object' &&
281
+ prefType?.unifyParentAndChildTypeChecks;
282
+ const unifiedSyntaxParentMatch = property && directNameMatch && (unifyParentAndChildTypeChecks || specificUnify);
283
+ isGenericMatch = isGenericMatch || Boolean(unifiedSyntaxParentMatch);
284
+
285
+ hasMatchingPreferredType = isGenericMatch ||
286
+ directNameMatch && !property;
287
+
288
+ return [
289
+ hasMatchingPreferredType, typName, isGenericMatch,
290
+ ];
291
+ };
292
+
293
+ /**
294
+ * Collect invalid type info.
295
+ * @param {string} type
296
+ * @param {string} value
297
+ * @param {string} tagName
298
+ * @param {string} nameInTag
299
+ * @param {number} idx
300
+ * @param {string|undefined} property
301
+ * @param {import('jsdoc-type-pratt-parser').NonRootResult} node
302
+ * @param {import('jsdoc-type-pratt-parser').NonRootResult|undefined} parentNode
303
+ * @param {(string|false|undefined)[][]} invalidTypes
304
+ * @returns {void}
305
+ */
306
+ const getInvalidTypes = (type, value, tagName, nameInTag, idx, property, node, parentNode, invalidTypes) => {
307
+ let typeNodeName = type === 'JsdocTypeAny' ? '*' : value;
308
+
309
+ const [
310
+ hasMatchingPreferredType,
311
+ typName,
312
+ isGenericMatch,
313
+ ] = getPreferredTypeInfo(type, typeNodeName, parentNode, property);
314
+
315
+ let preferred;
316
+ let types;
317
+ if (hasMatchingPreferredType) {
318
+ const preferredSetting = preferredTypes[typName];
319
+ typeNodeName = typName === '[]' ? typName : typeNodeName;
320
+
321
+ if (!preferredSetting) {
322
+ invalidTypes.push([
323
+ typeNodeName,
324
+ ]);
325
+ } else if (typeof preferredSetting === 'string') {
326
+ preferred = preferredSetting;
327
+ invalidTypes.push([
328
+ typeNodeName, preferred,
329
+ ]);
330
+ } else if (preferredSetting && typeof preferredSetting === 'object') {
331
+ const nextItem = preferredSetting.skipRootChecking && jsdocTagsWithPossibleType[idx + 1];
332
+
333
+ if (!nextItem || !nextItem.name.startsWith(`${nameInTag}.`)) {
334
+ preferred = preferredSetting.replacement;
335
+ invalidTypes.push([
336
+ typeNodeName,
337
+ preferred,
338
+ preferredSetting.message,
339
+ ]);
340
+ }
341
+ } else {
342
+ utils.reportSettings(
343
+ 'Invalid `settings.jsdoc.preferredTypes`. Values must be falsy, a string, or an object.',
344
+ );
345
+
346
+ return;
347
+ }
348
+ } else if (Object.entries(structuredTags).some(([
349
+ tag,
350
+ {
351
+ type: typs,
352
+ },
353
+ ]) => {
354
+ types = typs;
355
+
356
+ return tag === tagName &&
357
+ Array.isArray(types) &&
358
+ !types.includes(typeNodeName);
359
+ })) {
360
+ invalidTypes.push([
361
+ typeNodeName, types,
362
+ ]);
363
+ } else if (checkNativeTypes && !noDefaults && type === 'JsdocTypeName') {
364
+ preferred = checkNativeTypes(
365
+ preferredTypes, typeNodeName, preferred, parentNode, invalidTypes,
366
+ );
367
+ }
368
+
369
+ // For fixer
370
+ if (preferred) {
371
+ adjustNames(type, preferred, isGenericMatch, typeNodeName, node, parentNode);
372
+ }
373
+ };
374
+
375
+ for (const [
376
+ idx,
377
+ jsdocTag,
378
+ ] of jsdocTagsWithPossibleType.entries()) {
379
+ /** @type {(string|false|undefined)[][]} */
380
+ const invalidTypes = [];
381
+ let typeAst;
382
+
383
+ try {
384
+ typeAst = mode === 'permissive' ? tryParse(jsdocTag.type) : parse(jsdocTag.type, mode);
385
+ } catch {
386
+ continue;
387
+ }
388
+
389
+ const {
390
+ name: nameInTag,
391
+ tag: tagName,
392
+ } = jsdocTag;
393
+
394
+ traverse(typeAst, (node, parentNode, property) => {
395
+ const {
396
+ type,
397
+ value,
398
+ } =
399
+ /**
400
+ * @type {import('jsdoc-type-pratt-parser').NameResult}
401
+ */ (node);
402
+ if (![
403
+ 'JsdocTypeAny', 'JsdocTypeName',
404
+ ].includes(type)) {
405
+ return;
406
+ }
407
+
408
+ getInvalidTypes(type, value, tagName, nameInTag, idx, property, node, parentNode, invalidTypes);
409
+ });
410
+
411
+ if (invalidTypes.length) {
412
+ const fixedType = stringify(typeAst);
413
+
414
+ /**
415
+ * @type {import('eslint').Rule.ReportFixer}
416
+ */
417
+ const fix = (fixer) => {
418
+ return fixer.replaceText(
419
+ jsdocNode,
420
+ sourceCode.getText(jsdocNode).replace(
421
+ `{${jsdocTag.type}}`,
422
+ `{${fixedType}}`,
423
+ ),
424
+ );
425
+ };
426
+
427
+ for (const [
428
+ badType,
429
+ preferredType = '',
430
+ msg,
431
+ ] of invalidTypes) {
432
+ const tagValue = jsdocTag.name ? ` "${jsdocTag.name}"` : '';
433
+ if (exemptTagContexts.some(({
434
+ tag,
435
+ types,
436
+ }) => {
437
+ return tag === tagName &&
438
+ (types === true || types.includes(jsdocTag.type));
439
+ })) {
440
+ continue;
441
+ }
442
+
443
+ report(
444
+ msg ||
445
+ `Invalid JSDoc @${tagName}${tagValue} type "${badType}"` +
446
+ (preferredType ? '; ' : '.') +
447
+ (preferredType ? `prefer: ${JSON.stringify(preferredType)}.` : ''),
448
+ preferredType ? fix : null,
449
+ jsdocTag,
450
+ msg ? {
451
+ tagName,
452
+ tagValue,
453
+ } : undefined,
454
+ );
455
+ }
456
+ }
457
+ }
458
+ },
459
+ {
460
+ iterateAllJsdocs: true,
461
+ meta: {
462
+ docs: {
463
+ description,
464
+ url,
465
+ },
466
+ fixable: 'code',
467
+ schema,
468
+ type: 'suggestion',
469
+ },
470
+ },
471
+ );
472
+ };
package/src/index-cjs.js CHANGED
@@ -1,6 +1,9 @@
1
1
  import {
2
2
  buildForbidRuleDefinition,
3
3
  } from './buildForbidRuleDefinition.js';
4
+ import {
5
+ buildRejectOrPreferRuleDefinition,
6
+ } from './buildRejectOrPreferRuleDefinition.js';
4
7
  import {
5
8
  getJsdocProcessorPlugin,
6
9
  } from './getJsdocProcessorPlugin.js';
@@ -107,6 +110,33 @@ index.rules = {
107
110
  'no-restricted-syntax': noRestrictedSyntax,
108
111
  'no-types': noTypes,
109
112
  'no-undefined-types': noUndefinedTypes,
113
+ 'reject-any-type': buildRejectOrPreferRuleDefinition({
114
+ description: 'Reports use of `any` or `*` type',
115
+ overrideSettings: {
116
+ '*': {
117
+ message: 'Prefer a more specific type to `*`',
118
+ replacement: false,
119
+ unifyParentAndChildTypeChecks: true,
120
+ },
121
+ any: {
122
+ message: 'Prefer a more specific type to `any`',
123
+ replacement: false,
124
+ unifyParentAndChildTypeChecks: true,
125
+ },
126
+ },
127
+ url: 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/reject-any-type.md#repos-sticky-header',
128
+ }),
129
+ 'reject-function-type': buildRejectOrPreferRuleDefinition({
130
+ description: 'Reports use of `Function` type',
131
+ overrideSettings: {
132
+ Function: {
133
+ message: 'Prefer a more specific type to `Function`',
134
+ replacement: false,
135
+ unifyParentAndChildTypeChecks: true,
136
+ },
137
+ },
138
+ url: 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/reject-function-type.md#repos-sticky-header',
139
+ }),
110
140
  'require-asterisk-prefix': requireAsteriskPrefix,
111
141
  'require-description': requireDescription,
112
142
  'require-description-complete-sentence': requireDescriptionCompleteSentence,
@@ -122,7 +152,7 @@ index.rules = {
122
152
  message: '@next should have a type',
123
153
  },
124
154
  ],
125
- description: 'Requires a type for @next tags',
155
+ description: 'Requires a type for `@next` tags',
126
156
  url: 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-next-type.md#repos-sticky-header',
127
157
  }),
128
158
  'require-param': requireParam,
@@ -147,7 +177,7 @@ index.rules = {
147
177
  message: '@throws should have a type',
148
178
  },
149
179
  ],
150
- description: 'Requires a type for @throws tags',
180
+ description: 'Requires a type for `@throws` tags',
151
181
  url: 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-throws-type.md#repos-sticky-header',
152
182
  }),
153
183
  'require-yields': requireYields,
@@ -160,7 +190,7 @@ index.rules = {
160
190
  message: '@yields should have a type',
161
191
  },
162
192
  ],
163
- description: 'Requires a type for @yields tags',
193
+ description: 'Requires a type for `@yields` tags',
164
194
  url: 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-yields-type.md#repos-sticky-header',
165
195
  }),
166
196
  'sort-tags': sortTags,
@@ -218,6 +248,8 @@ const createRecommendedRuleset = (warnOrError, flatName) => {
218
248
  'jsdoc/no-restricted-syntax': 'off',
219
249
  'jsdoc/no-types': 'off',
220
250
  'jsdoc/no-undefined-types': warnOrError,
251
+ 'jsdoc/reject-any-type': warnOrError,
252
+ 'jsdoc/reject-function-type': warnOrError,
221
253
  'jsdoc/require-asterisk-prefix': 'off',
222
254
  'jsdoc/require-description': 'off',
223
255
  'jsdoc/require-description-complete-sentence': 'off',