@depup/eslint-plugin-jsdoc 64.3.4-depup.0 → 64.3.5-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 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.4 |
17
- | Processed | 2026-09-02 |
16
+ | Original | [eslint-plugin-jsdoc](https://www.npmjs.com/package/eslint-plugin-jsdoc) @ 64.3.5 |
17
+ | Processed | 2026-09-04 |
18
18
  | Smoke test | passed |
19
- | Deps updated | 2 |
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
- "@es-joy/jsdoccomment": {
4
- "from": "~0.95.1",
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-04T00:48:38.238Z",
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": "^0.96.0",
8
+ "@es-joy/jsdoccomment": "~0.96.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,27 +41,27 @@
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.2.0",
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.67.0",
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.8.1",
54
+ "eslint": "10.9.1",
55
55
  "eslint-config-canonical": "^47.4.2",
56
56
  "gitdown": "^4.1.1",
57
57
  "glob": "^13.0.6",
58
- "globals": "^17.11.0",
58
+ "globals": "^17.12.0",
59
59
  "husky": "^9.1.7",
60
- "jsdoc-type-pratt-parser": "^9.1.2",
60
+ "jsdoc-type-pratt-parser": "^9.2.1",
61
61
  "json-schema": "^0.4.0",
62
- "json-schema-to-typescript": "^15.0.4",
63
- "lint-staged": "^17.3.0",
64
- "mocha": "^11.8.0",
62
+ "json-schema-to-typescript": "^16.0.0",
63
+ "lint-staged": "^17.4.1",
64
+ "mocha": "^12.0.0",
65
65
  "open-editor": "^6.0.0",
66
66
  "playwright": "^1.62.1",
67
67
  "replace": "^1.2.2",
@@ -70,7 +70,7 @@
70
70
  "sinon": "^22.1.0",
71
71
  "ts-api-utils": "^2.5.0",
72
72
  "typescript": "6.0.3",
73
- "typescript-eslint": "8.67.0"
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.4-depup.0",
165
+ "version": "64.3.5-depup.0",
166
166
  "depup": {
167
- "changes": {
168
- "@es-joy/jsdoccomment": {
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.4",
180
- "processedAt": "2026-09-02T00:33:49.226Z",
170
+ "originalVersion": "64.3.5",
171
+ "processedAt": "2026-09-04T00:49:00.194Z",
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,52 @@ 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
+ * Whether every element of `tupleType` is a literal type, so a `const`
368
+ * assertion would reproduce the same element types (`['foo', 1]` but not
369
+ * `[string]`).
370
+ * @param {any} tupleType `ts.Type`
371
+ * @returns {boolean}
372
+ */
373
+ const tupleElementsAllLiteral = (tupleType) => {
374
+ const elements = checker.getTypeArguments(tupleType);
375
+ return elements.length > 0 && elements.every(isLiteralType);
376
+ };
377
+
378
+ /**
379
+ * Reports an array-literal tuple assertion, offering (under `enableFixer`) a
380
+ * rewrite to the equivalent, more concise `const` assertion.
381
+ * @returns {void}
382
+ */
383
+ const reportPreferConst = () => {
384
+ utils.reportJSDoc(
385
+ preferConstMessage,
386
+ types[0],
387
+ enableFixer ? convertToConst : null,
388
+ false,
389
+ {
390
+ type: assertedTypeStr,
391
+ },
392
+ );
393
+ };
394
+
330
395
  // Positions where a bare expression of any precedence is valid and equivalent
331
396
  // to the parenthesized form, so a redundant `/** @type {T} */ (expr)` cast can
332
397
  // be unwrapped to `expr` without changing meaning.
@@ -372,6 +437,14 @@ export default iterateJsdoc(({
372
437
  const declInferredType = checker.getTypeAtLocation(declInitTsNode);
373
438
  const declAssertedType = checker.getTypeFromTypeNode(jsdocTypeNode);
374
439
 
440
+ if (isTupleConversionIdiom(declAssertedType, decl.init)) {
441
+ if (preferConstToLiteralTuples && tupleElementsAllLiteral(declAssertedType)) {
442
+ reportPreferConst();
443
+ }
444
+
445
+ return;
446
+ }
447
+
375
448
  if (isRedundantAssertion(declInferredType, declAssertedType)) {
376
449
  utils.reportJSDoc(message, types[0], fixer, true, {
377
450
  type: assertedTypeStr,
@@ -441,6 +514,14 @@ export default iterateJsdoc(({
441
514
  checker.getTypeAtLocation(exprTsNode);
442
515
  const castAssertedType = checker.getTypeFromTypeNode(typeTag.typeExpression.type);
443
516
 
517
+ if (isTupleConversionIdiom(castAssertedType, node)) {
518
+ if (preferConstToLiteralTuples && tupleElementsAllLiteral(castAssertedType)) {
519
+ reportPreferConst();
520
+ }
521
+
522
+ return;
523
+ }
524
+
444
525
  if (!isRedundantAssertion(castInferredType, castAssertedType)) {
445
526
  return;
446
527
  }
@@ -503,6 +584,10 @@ export default iterateJsdoc(({
503
584
  description: 'Whether to enable the fixer that removes the redundant `@type` tag (and the JSDoc block if it becomes empty). Defaults to `true`.',
504
585
  type: 'boolean',
505
586
  },
587
+ preferConstToLiteralTuples: {
588
+ 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`.',
589
+ type: 'boolean',
590
+ },
506
591
  treatAnyAsRedundant: {
507
592
  description: 'Whether to treat `any` type casts as redundant',
508
593
  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
  */