Skip to content

Commit 4349209

Browse files
committed
fix(prefer-import-tag): ensure import is a valid identifier; fixes #1572
1 parent 0b3cbee commit 4349209

File tree

5 files changed

+86
-5
lines changed

5 files changed

+86
-5
lines changed

docs/rules/prefer-import-tag.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,15 @@ let foo;
315315
/** @type {import('foo').default} */
316316
let foo;
317317
// Message: Inline `import()` found; prefer `@import`
318+
319+
/** @type { import('@typescript-eslint/utils').TSESLint.FlatConfig.Config['rules'] } */
320+
// Message: Inline `import()` found; prefer `@import`
321+
322+
/** @type { import('node:zlib').createGzip } */
323+
// Message: Inline `import()` found; prefer `@import`
324+
325+
/** @type { import('./lib/someFile.js').someImport } */
326+
// Message: Inline `import()` found; prefer `@import`
318327
````
319328

320329

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
"replace": "^1.2.2",
6868
"rimraf": "^6.0.1",
6969
"semantic-release": "^24.2.9",
70+
"to-valid-identifier": "^0.1.1",
7071
"typescript": "5.9.3",
7172
"typescript-eslint": "^8.46.0"
7273
},

pnpm-lock.yaml

Lines changed: 24 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/rules/preferImportTag.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
import {
1414
parseImportsExports,
1515
} from 'parse-imports-exports';
16+
import toValidIdentifier from 'to-valid-identifier';
1617

1718
export default iterateJsdoc(({
1819
context,
@@ -133,10 +134,11 @@ export default iterateJsdoc(({
133134
}
134135

135136
/**
136-
* @param {string} matchingName
137+
* @param {string} name
137138
* @param {string[]} extrPathSegments
138139
*/
139-
const getFixer = (matchingName, extrPathSegments) => {
140+
const getFixer = (name, extrPathSegments) => {
141+
const matchingName = toValidIdentifier(name);
140142
return () => {
141143
/** @type {import('jsdoc-type-pratt-parser').NamePathResult|undefined} */
142144
let node = nodes.at(0);
@@ -369,7 +371,7 @@ export default iterateJsdoc(({
369371
return fixer.insertTextBefore(
370372
// @ts-expect-error Ok
371373
commentNodes[0] ?? programNode,
372-
`/** @import * as ${element.value} from '${element.value}'; */${
374+
`/** @import * as ${toValidIdentifier(element.value)} from '${element.value}'; */${
373375
commentNodes[0] ? '\n' + indent : ''
374376
}`,
375377
);
@@ -422,10 +424,13 @@ export default iterateJsdoc(({
422424
// @ts-expect-error Ok
423425
commentNodes[0] ?? programNode,
424426
outputType === 'namespaced-import' ?
425-
`/** @import * as ${element.value} from '${element.value}'; */${
427+
`/** @import * as ${toValidIdentifier(element.value)} from '${element.value}'; */${
426428
commentNodes[0] ? '\n' + indent : ''
427429
}` :
428-
`/** @import { ${pathSegments.at(-1)} } from '${element.value}'; */${
430+
`/** @import { ${toValidIdentifier(
431+
/* c8 ignore next -- TS */
432+
pathSegments.at(-1) ?? '',
433+
)} } from '${element.value}'; */${
429434
commentNodes[0] ? '\n' + indent : ''
430435
}`,
431436
);

test/rules/assertions/preferImportTag.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -906,6 +906,48 @@ let foo;
906906
let foo;
907907
`,
908908
},
909+
{
910+
code: `
911+
/** @type { import('@typescript-eslint/utils').TSESLint.FlatConfig.Config['rules'] } */
912+
`,
913+
errors: [
914+
{
915+
line: 2,
916+
message: 'Inline `import()` found; prefer `@import`',
917+
},
918+
],
919+
output: `/** @import * as $12$typescript$j$eslint$l$utils from '@typescript-eslint/utils'; */
920+
/** @type {$12$typescript$j$eslint$l$utils.TSESLint.FlatConfig.Config['rules']} */
921+
`,
922+
},
923+
{
924+
code: `
925+
/** @type { import('node:zlib').createGzip } */
926+
`,
927+
errors: [
928+
{
929+
line: 2,
930+
message: 'Inline `import()` found; prefer `@import`',
931+
},
932+
],
933+
output: `/** @import * as node$w$zlib from 'node:zlib'; */
934+
/** @type {node$w$zlib.createGzip} */
935+
`,
936+
},
937+
{
938+
code: `
939+
/** @type { import('./lib/someFile.js').someImport } */
940+
`,
941+
errors: [
942+
{
943+
line: 2,
944+
message: 'Inline `import()` found; prefer `@import`',
945+
},
946+
],
947+
output: `/** @import * as $k$$l$lib$l$someFile$k$js from './lib/someFile.js'; */
948+
/** @type {$k$$l$lib$l$someFile$k$js.someImport} */
949+
`,
950+
},
909951
],
910952
valid: [
911953
{

0 commit comments

Comments
 (0)