Skip to content

Commit 1d55ad1

Browse files
committed
False positives for type-only exports in vue/no-export-in-script-setup rule
1 parent 6c64a09 commit 1d55ad1

File tree

3 files changed

+93
-7
lines changed

3 files changed

+93
-7
lines changed

lib/rules/no-export-in-script-setup.js

+25-4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66

77
const utils = require('../utils')
88

9+
/**
10+
* @typedef {import('@typescript-eslint/types').TSESTree.ExportAllDeclaration} TSESTreeExportAllDeclaration
11+
* @typedef {import('@typescript-eslint/types').TSESTree.ExportDefaultDeclaration} TSESTreeExportDefaultDeclaration
12+
* @typedef {import('@typescript-eslint/types').TSESTree.ExportNamedDeclaration} TSESTreeExportNamedDeclaration
13+
*/
14+
915
module.exports = {
1016
meta: {
1117
type: 'problem',
@@ -23,17 +29,32 @@ module.exports = {
2329
/** @param {RuleContext} context */
2430
create(context) {
2531
/** @param {ExportAllDeclaration | ExportDefaultDeclaration | ExportNamedDeclaration} node */
26-
function report(node) {
32+
function verify(node) {
33+
const tsNode =
34+
/** @type {TSESTreeExportAllDeclaration | TSESTreeExportDefaultDeclaration | TSESTreeExportNamedDeclaration} */ (
35+
node
36+
)
37+
if (tsNode.exportKind === 'type') {
38+
return
39+
}
40+
if (tsNode.type === 'ExportNamedDeclaration') {
41+
if (
42+
tsNode.specifiers.length > 0 &&
43+
tsNode.specifiers.every((spec) => spec.exportKind === 'type')
44+
) {
45+
return
46+
}
47+
}
2748
context.report({
2849
node,
2950
messageId: 'forbidden'
3051
})
3152
}
3253

3354
return utils.defineScriptSetupVisitor(context, {
34-
ExportAllDeclaration: report,
35-
ExportDefaultDeclaration: report,
36-
ExportNamedDeclaration: report
55+
ExportAllDeclaration: verify,
56+
ExportDefaultDeclaration: verify,
57+
ExportNamedDeclaration: verify
3758
})
3859
}
3960
}

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
"@types/natural-compare": "^1.4.0",
6666
"@types/node": "^13.13.5",
6767
"@types/semver": "^7.2.0",
68-
"@typescript-eslint/parser": "^5.0.0-0",
68+
"@typescript-eslint/parser": "^5.4.0",
6969
"@vuepress/plugin-pwa": "^1.4.1",
7070
"acorn": "^8.5.0",
7171
"env-cmd": "^10.1.0",
@@ -82,7 +82,7 @@
8282
"mocha": "^7.1.2",
8383
"nyc": "^15.1.0",
8484
"prettier": "^2.4.1",
85-
"typescript": "^4.4.3",
85+
"typescript": "^4.5.0-0",
8686
"vue-eslint-editor": "^1.1.0",
8787
"vuepress": "^1.8.2"
8888
}

tests/lib/rules/no-export-in-script-setup.js

+66-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// Requirements
99
// ------------------------------------------------------------------------------
1010

11+
const semver = require('semver')
1112
const eslint = require('eslint')
1213
const rule = require('../../../lib/rules/no-export-in-script-setup')
1314

@@ -48,7 +49,43 @@ ruleTester.run('no-export-in-script-setup', rule, {
4849
let foo;
4950
</script>
5051
`
51-
}
52+
},
53+
...(semver.gte(
54+
require('@typescript-eslint/parser/package.json').version,
55+
'5.4.0'
56+
) &&
57+
semver.satisfies(require('typescript/package.json').version, '>=4.5.0-0')
58+
? [
59+
{
60+
filename: 'test.vue',
61+
code: `
62+
<script setup lang="ts">
63+
export { type Foo } from "foo"
64+
export type Bar = {}
65+
export interface Bar {}
66+
</script>
67+
`,
68+
parser: require.resolve('vue-eslint-parser'),
69+
parserOptions: {
70+
parser: require.resolve('@typescript-eslint/parser')
71+
}
72+
}
73+
]
74+
: [
75+
{
76+
filename: 'test.vue',
77+
code: `
78+
<script setup lang="ts">
79+
export type Bar = {}
80+
export interface Bar {}
81+
</script>
82+
`,
83+
parser: require.resolve('vue-eslint-parser'),
84+
parserOptions: {
85+
parser: require.resolve('@typescript-eslint/parser')
86+
}
87+
}
88+
])
5289
],
5390

5491
invalid: [
@@ -102,6 +139,34 @@ ruleTester.run('no-export-in-script-setup', rule, {
102139
line: 8
103140
}
104141
]
142+
},
143+
{
144+
filename: 'test.vue',
145+
code: `
146+
<script setup lang="ts">
147+
export const Foo = {}
148+
export enum Bar {}
149+
export {}
150+
</script>
151+
`,
152+
parser: require.resolve('vue-eslint-parser'),
153+
parserOptions: {
154+
parser: require.resolve('@typescript-eslint/parser')
155+
},
156+
errors: [
157+
{
158+
message: '`<script setup>` cannot contain ES module exports.',
159+
line: 3
160+
},
161+
{
162+
message: '`<script setup>` cannot contain ES module exports.',
163+
line: 4
164+
},
165+
{
166+
message: '`<script setup>` cannot contain ES module exports.',
167+
line: 5
168+
}
169+
]
105170
}
106171
]
107172
})

0 commit comments

Comments
 (0)