@depup/eslint-plugin-jsdoc 64.3.4-depup.0 → 64.3.6-depup.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/README.md +3 -10
- package/changes.json +3 -12
- package/dist/rules.d.ts +4 -0
- package/package.json +16 -25
- package/src/rules/noUnnecessaryTypeAssertion.js +144 -0
- package/src/rules/requireJsdoc.js +0 -1
- package/src/rules.d.ts +4 -0
package/README.md
CHANGED
|
@@ -13,17 +13,10 @@ npm install @depup/eslint-plugin-jsdoc
|
|
|
13
13
|
|
|
14
14
|
| Field | Value |
|
|
15
15
|
|-------|-------|
|
|
16
|
-
| Original | [eslint-plugin-jsdoc](https://www.npmjs.com/package/eslint-plugin-jsdoc) @ 64.3.
|
|
17
|
-
| Processed | 2026-09-
|
|
16
|
+
| Original | [eslint-plugin-jsdoc](https://www.npmjs.com/package/eslint-plugin-jsdoc) @ 64.3.6 |
|
|
17
|
+
| Processed | 2026-09-06 |
|
|
18
18
|
| Smoke test | passed |
|
|
19
|
-
| Deps updated |
|
|
20
|
-
|
|
21
|
-
## Dependency Changes
|
|
22
|
-
|
|
23
|
-
| Dependency | From | To |
|
|
24
|
-
|------------|------|-----|
|
|
25
|
-
| @es-joy/jsdoccomment | ~0.95.1 | ^0.96.0 |
|
|
26
|
-
| @typescript-eslint/utils | ^8.68.0 | ^8.69.0 |
|
|
19
|
+
| Deps updated | 0 |
|
|
27
20
|
|
|
28
21
|
---
|
|
29
22
|
|
package/changes.json
CHANGED
|
@@ -1,14 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"bumped": {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
"to": "^0.96.0"
|
|
6
|
-
},
|
|
7
|
-
"@typescript-eslint/utils": {
|
|
8
|
-
"from": "^8.68.0",
|
|
9
|
-
"to": "^8.69.0"
|
|
10
|
-
}
|
|
11
|
-
},
|
|
12
|
-
"timestamp": "2026-09-02T00:33:20.653Z",
|
|
13
|
-
"totalUpdated": 2
|
|
2
|
+
"bumped": {},
|
|
3
|
+
"timestamp": "2026-09-06T00:59:03.732Z",
|
|
4
|
+
"totalUpdated": 0
|
|
14
5
|
}
|
package/dist/rules.d.ts
CHANGED
|
@@ -1324,6 +1324,10 @@ export interface Rules {
|
|
|
1324
1324
|
* Whether to enable the fixer that removes the redundant `@type` tag (and the JSDoc block if it becomes empty). Defaults to `true`.
|
|
1325
1325
|
*/
|
|
1326
1326
|
enableFixer?: boolean;
|
|
1327
|
+
/**
|
|
1328
|
+
* Whether to report a non-`const` literal-tuple assertion on an array literal (e.g. `/** @type {['foo']} * / (['foo'])`) and fix it to the equivalent, more concise `/** @type {const} * /` assertion. Defaults to `false`.
|
|
1329
|
+
*/
|
|
1330
|
+
preferConstToLiteralTuples?: boolean;
|
|
1327
1331
|
/**
|
|
1328
1332
|
* Whether to treat `any` type casts as redundant
|
|
1329
1333
|
*/
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"url": "http://gajus.com"
|
|
6
6
|
},
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@es-joy/jsdoccomment": "
|
|
8
|
+
"@es-joy/jsdoccomment": "~0.97.0",
|
|
9
9
|
"@es-joy/resolve.exports": "1.2.0",
|
|
10
10
|
"@typescript-eslint/utils": "^8.69.0",
|
|
11
11
|
"are-docs-informative": "^0.1.1",
|
|
@@ -41,36 +41,36 @@
|
|
|
41
41
|
"@types/estree": "^1.0.9",
|
|
42
42
|
"@types/json-schema": "^7.0.15",
|
|
43
43
|
"@types/mocha": "^10.0.10",
|
|
44
|
-
"@types/node": "^26.
|
|
44
|
+
"@types/node": "^26.4.1",
|
|
45
45
|
"@types/semver": "^7.8.0",
|
|
46
46
|
"@types/spdx-expression-parse": "^4.0.0",
|
|
47
|
-
"@typescript-eslint/types": "8.
|
|
47
|
+
"@typescript-eslint/types": "8.69.0",
|
|
48
48
|
"babel-plugin-add-module-exports": "^1.0.4",
|
|
49
49
|
"babel-plugin-transform-import-meta": "^3.0.0",
|
|
50
50
|
"c8": "^12.0.0",
|
|
51
51
|
"camelcase": "^9.0.0",
|
|
52
52
|
"chai": "^6.2.2",
|
|
53
53
|
"decamelize": "^6.0.1",
|
|
54
|
-
"eslint": "10.
|
|
54
|
+
"eslint": "10.10.0",
|
|
55
55
|
"eslint-config-canonical": "^47.4.2",
|
|
56
56
|
"gitdown": "^4.1.1",
|
|
57
57
|
"glob": "^13.0.6",
|
|
58
|
-
"globals": "^17.
|
|
58
|
+
"globals": "^17.12.0",
|
|
59
59
|
"husky": "^9.1.7",
|
|
60
|
-
"jsdoc-type-pratt-parser": "^9.1
|
|
60
|
+
"jsdoc-type-pratt-parser": "^9.2.1",
|
|
61
61
|
"json-schema": "^0.4.0",
|
|
62
|
-
"json-schema-to-typescript": "^
|
|
63
|
-
"lint-staged": "^17.
|
|
64
|
-
"mocha": "^
|
|
62
|
+
"json-schema-to-typescript": "^16.0.0",
|
|
63
|
+
"lint-staged": "^17.5.0",
|
|
64
|
+
"mocha": "^12.0.0",
|
|
65
65
|
"open-editor": "^6.0.0",
|
|
66
|
-
"playwright": "^1.
|
|
66
|
+
"playwright": "^1.63.0",
|
|
67
67
|
"replace": "^1.2.2",
|
|
68
68
|
"rimraf": "^6.1.3",
|
|
69
69
|
"semantic-release": "^25.0.9",
|
|
70
70
|
"sinon": "^22.1.0",
|
|
71
71
|
"ts-api-utils": "^2.5.0",
|
|
72
72
|
"typescript": "6.0.3",
|
|
73
|
-
"typescript-eslint": "8.
|
|
73
|
+
"typescript-eslint": "8.69.0"
|
|
74
74
|
},
|
|
75
75
|
"engines": {
|
|
76
76
|
"node": "^22.22.2 || >=24.15.0"
|
|
@@ -162,22 +162,13 @@
|
|
|
162
162
|
"test-cov": "TIMING=1 c8 --reporter text pnpm run test-no-cov",
|
|
163
163
|
"test-index": "pnpm run test-no-cov test/rules/index.js"
|
|
164
164
|
},
|
|
165
|
-
"version": "64.3.
|
|
165
|
+
"version": "64.3.6-depup.0",
|
|
166
166
|
"depup": {
|
|
167
|
-
"changes": {
|
|
168
|
-
|
|
169
|
-
"from": "~0.95.1",
|
|
170
|
-
"to": "^0.96.0"
|
|
171
|
-
},
|
|
172
|
-
"@typescript-eslint/utils": {
|
|
173
|
-
"from": "^8.68.0",
|
|
174
|
-
"to": "^8.69.0"
|
|
175
|
-
}
|
|
176
|
-
},
|
|
177
|
-
"depsUpdated": 2,
|
|
167
|
+
"changes": {},
|
|
168
|
+
"depsUpdated": 0,
|
|
178
169
|
"originalPackage": "eslint-plugin-jsdoc",
|
|
179
|
-
"originalVersion": "64.3.
|
|
180
|
-
"processedAt": "2026-09-
|
|
170
|
+
"originalVersion": "64.3.6",
|
|
171
|
+
"processedAt": "2026-09-06T00:59:25.028Z",
|
|
181
172
|
"smokeTest": "passed"
|
|
182
173
|
}
|
|
183
174
|
}
|
|
@@ -87,6 +87,7 @@ export default iterateJsdoc(({
|
|
|
87
87
|
// https://typescript-eslint.io/rules/no-unnecessary-type-assertion/
|
|
88
88
|
checkLiteralConstAssertions = false,
|
|
89
89
|
enableFixer = true,
|
|
90
|
+
preferConstToLiteralTuples = false,
|
|
90
91
|
treatAnyAsRedundant = false,
|
|
91
92
|
typesToIgnore = [],
|
|
92
93
|
} = context.options[0] ?? {};
|
|
@@ -154,6 +155,24 @@ export default iterateJsdoc(({
|
|
|
154
155
|
'The @type tag declaring "{{ type }}" is redundant as TypeScript infers it automatically for literals.' :
|
|
155
156
|
'The @type tag declaring "{{ type }}" is redundant as TypeScript infers it automatically.';
|
|
156
157
|
|
|
158
|
+
const preferConstMessage =
|
|
159
|
+
'The @type tag declaring "{{ type }}" is better written as the "const" assertion `/** @type {const} */` (TypeScript 4.5+).';
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Rewrites the reported `@type` tag's type to `const`.
|
|
163
|
+
* @returns {void}
|
|
164
|
+
*/
|
|
165
|
+
const convertToConst = () => {
|
|
166
|
+
for (const {
|
|
167
|
+
tokens,
|
|
168
|
+
} of /** @type {import('comment-parser').Spec} */ (types[0]).source) {
|
|
169
|
+
if (tokens.type) {
|
|
170
|
+
tokens.type = '{const}';
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
|
|
157
176
|
/**
|
|
158
177
|
* Whether `inferredType` is a generic reference carrying `any` type arguments
|
|
159
178
|
* that `assertedType` replaces with concrete ones (e.g. an untyped
|
|
@@ -327,6 +346,97 @@ export default iterateJsdoc(({
|
|
|
327
346
|
checker.isTypeAssignableTo(assertedBaseType, inferredBaseType);
|
|
328
347
|
};
|
|
329
348
|
|
|
349
|
+
/**
|
|
350
|
+
* A non-`const` tuple type annotation on an array literal (asserting `['foo']`
|
|
351
|
+
* onto `['foo']`) turns the literal's inferred `T[]` into a tuple; since the
|
|
352
|
+
* literal only takes that tuple type *from* the assertion, the assertion is
|
|
353
|
+
* never genuinely redundant even though the contextually-typed expression
|
|
354
|
+
* echoes the asserted tuple straight back. It is the pre-TypeScript-4.5
|
|
355
|
+
* stand-in for a `const` assertion.
|
|
356
|
+
* @param {any} assertedType `ts.Type`
|
|
357
|
+
* @param {import('@typescript-eslint/utils').TSESTree.Node | null | undefined} operand
|
|
358
|
+
* @returns {boolean}
|
|
359
|
+
*/
|
|
360
|
+
const isTupleConversionIdiom = (assertedType, operand) => {
|
|
361
|
+
return assertedTypeStr !== 'const' &&
|
|
362
|
+
operand?.type === 'ArrayExpression' &&
|
|
363
|
+
checker.isTupleType(assertedType);
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* An array-literal annotation whose element type is a literal (or union of
|
|
368
|
+
* literals) — `type {ViewType[]}` on `['single-panel', 'user']` —
|
|
369
|
+
* narrows the element type that the bare literal would widen (`string[]` ->
|
|
370
|
+
* `ViewType[]`). Like the tuple idiom, the literal takes that element type
|
|
371
|
+
* only *from* the annotation, so the contextually-typed initializer echoes
|
|
372
|
+
* the asserted array straight back and the genuine narrowing looks redundant.
|
|
373
|
+
* @param {any} assertedType `ts.Type`
|
|
374
|
+
* @param {import('@typescript-eslint/utils').TSESTree.Node | null | undefined} operand
|
|
375
|
+
* @returns {boolean}
|
|
376
|
+
*/
|
|
377
|
+
const narrowsArrayLiteralElement = (assertedType, operand) => {
|
|
378
|
+
if (operand?.type !== 'ArrayExpression' || !checker.isArrayType(assertedType)) {
|
|
379
|
+
return false;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
const [
|
|
383
|
+
elementType,
|
|
384
|
+
] = checker.getTypeArguments(assertedType);
|
|
385
|
+
return isLiteralType(elementType);
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Whether `operand` is an object literal carrying a method or function-valued
|
|
390
|
+
* property. Under a surrounding `@type` object annotation such a function is
|
|
391
|
+
* contextually typed by the annotation — its otherwise-implicit-`any`
|
|
392
|
+
* parameters (and hence its signature) come straight from it — so
|
|
393
|
+
* `getTypeAtLocation` echoes the asserted object shape back and a genuine
|
|
394
|
+
* typing looks redundant. As elsewhere in this rule the uncontaminated type
|
|
395
|
+
* cannot be recovered here, so such literals are left alone (at the cost of
|
|
396
|
+
* missing the rare object annotation that only restates a fully
|
|
397
|
+
* self-evident method signature).
|
|
398
|
+
* @param {import('@typescript-eslint/utils').TSESTree.Node | null | undefined} operand
|
|
399
|
+
* @returns {boolean}
|
|
400
|
+
*/
|
|
401
|
+
const hasContextuallyTypedFunctionMember = (operand) => {
|
|
402
|
+
return operand?.type === 'ObjectExpression' &&
|
|
403
|
+
operand.properties.some((property) => {
|
|
404
|
+
return property.type === 'Property' && (
|
|
405
|
+
property.value.type === 'FunctionExpression' ||
|
|
406
|
+
property.value.type === 'ArrowFunctionExpression'
|
|
407
|
+
);
|
|
408
|
+
});
|
|
409
|
+
};
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Whether every element of `tupleType` is a literal type, so a `const`
|
|
413
|
+
* assertion would reproduce the same element types (`['foo', 1]` but not
|
|
414
|
+
* `[string]`).
|
|
415
|
+
* @param {any} tupleType `ts.Type`
|
|
416
|
+
* @returns {boolean}
|
|
417
|
+
*/
|
|
418
|
+
const tupleElementsAllLiteral = (tupleType) => {
|
|
419
|
+
const elements = checker.getTypeArguments(tupleType);
|
|
420
|
+
return elements.length > 0 && elements.every(isLiteralType);
|
|
421
|
+
};
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* Reports an array-literal tuple assertion, offering (under `enableFixer`) a
|
|
425
|
+
* rewrite to the equivalent, more concise `const` assertion.
|
|
426
|
+
* @returns {void}
|
|
427
|
+
*/
|
|
428
|
+
const reportPreferConst = () => {
|
|
429
|
+
utils.reportJSDoc(
|
|
430
|
+
preferConstMessage,
|
|
431
|
+
types[0],
|
|
432
|
+
enableFixer ? convertToConst : null,
|
|
433
|
+
false,
|
|
434
|
+
{
|
|
435
|
+
type: assertedTypeStr,
|
|
436
|
+
},
|
|
437
|
+
);
|
|
438
|
+
};
|
|
439
|
+
|
|
330
440
|
// Positions where a bare expression of any precedence is valid and equivalent
|
|
331
441
|
// to the parenthesized form, so a redundant `/** @type {T} */ (expr)` cast can
|
|
332
442
|
// be unwrapped to `expr` without changing meaning.
|
|
@@ -372,6 +482,21 @@ export default iterateJsdoc(({
|
|
|
372
482
|
const declInferredType = checker.getTypeAtLocation(declInitTsNode);
|
|
373
483
|
const declAssertedType = checker.getTypeFromTypeNode(jsdocTypeNode);
|
|
374
484
|
|
|
485
|
+
if (isTupleConversionIdiom(declAssertedType, decl.init)) {
|
|
486
|
+
if (preferConstToLiteralTuples && tupleElementsAllLiteral(declAssertedType)) {
|
|
487
|
+
reportPreferConst();
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
if (
|
|
494
|
+
narrowsArrayLiteralElement(declAssertedType, decl.init) ||
|
|
495
|
+
hasContextuallyTypedFunctionMember(decl.init)
|
|
496
|
+
) {
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
|
|
375
500
|
if (isRedundantAssertion(declInferredType, declAssertedType)) {
|
|
376
501
|
utils.reportJSDoc(message, types[0], fixer, true, {
|
|
377
502
|
type: assertedTypeStr,
|
|
@@ -441,6 +566,21 @@ export default iterateJsdoc(({
|
|
|
441
566
|
checker.getTypeAtLocation(exprTsNode);
|
|
442
567
|
const castAssertedType = checker.getTypeFromTypeNode(typeTag.typeExpression.type);
|
|
443
568
|
|
|
569
|
+
if (isTupleConversionIdiom(castAssertedType, node)) {
|
|
570
|
+
if (preferConstToLiteralTuples && tupleElementsAllLiteral(castAssertedType)) {
|
|
571
|
+
reportPreferConst();
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
return;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
if (
|
|
578
|
+
narrowsArrayLiteralElement(castAssertedType, node) ||
|
|
579
|
+
hasContextuallyTypedFunctionMember(node)
|
|
580
|
+
) {
|
|
581
|
+
return;
|
|
582
|
+
}
|
|
583
|
+
|
|
444
584
|
if (!isRedundantAssertion(castInferredType, castAssertedType)) {
|
|
445
585
|
return;
|
|
446
586
|
}
|
|
@@ -503,6 +643,10 @@ export default iterateJsdoc(({
|
|
|
503
643
|
description: 'Whether to enable the fixer that removes the redundant `@type` tag (and the JSDoc block if it becomes empty). Defaults to `true`.',
|
|
504
644
|
type: 'boolean',
|
|
505
645
|
},
|
|
646
|
+
preferConstToLiteralTuples: {
|
|
647
|
+
description: 'Whether to report a non-`const` literal-tuple assertion on an array literal (e.g. `/** @type {[\'foo\']} */ ([\'foo\'])`) and fix it to the equivalent, more concise `/** @type {const} */` assertion. Defaults to `false`.',
|
|
648
|
+
type: 'boolean',
|
|
649
|
+
},
|
|
506
650
|
treatAnyAsRedundant: {
|
|
507
651
|
description: 'Whether to treat `any` type casts as redundant',
|
|
508
652
|
type: 'boolean',
|
package/src/rules.d.ts
CHANGED
|
@@ -1324,6 +1324,10 @@ export interface Rules {
|
|
|
1324
1324
|
* Whether to enable the fixer that removes the redundant `@type` tag (and the JSDoc block if it becomes empty). Defaults to `true`.
|
|
1325
1325
|
*/
|
|
1326
1326
|
enableFixer?: boolean;
|
|
1327
|
+
/**
|
|
1328
|
+
* Whether to report a non-`const` literal-tuple assertion on an array literal (e.g. `/** @type {['foo']} * / (['foo'])`) and fix it to the equivalent, more concise `/** @type {const} * /` assertion. Defaults to `false`.
|
|
1329
|
+
*/
|
|
1330
|
+
preferConstToLiteralTuples?: boolean;
|
|
1327
1331
|
/**
|
|
1328
1332
|
* Whether to treat `any` type casts as redundant
|
|
1329
1333
|
*/
|