From 1d55ad1d0d58f93919e236f1c7143a09e11b5c50 Mon Sep 17 00:00:00 2001 From: yosuke ota Date: Tue, 16 Nov 2021 12:19:12 +0900 Subject: [PATCH 1/2] False positives for type-only exports in `vue/no-export-in-script-setup` rule --- lib/rules/no-export-in-script-setup.js | 29 +++++++-- package.json | 4 +- tests/lib/rules/no-export-in-script-setup.js | 67 +++++++++++++++++++- 3 files changed, 93 insertions(+), 7 deletions(-) diff --git a/lib/rules/no-export-in-script-setup.js b/lib/rules/no-export-in-script-setup.js index b39231dfe..99b6ba113 100644 --- a/lib/rules/no-export-in-script-setup.js +++ b/lib/rules/no-export-in-script-setup.js @@ -6,6 +6,12 @@ const utils = require('../utils') +/** + * @typedef {import('@typescript-eslint/types').TSESTree.ExportAllDeclaration} TSESTreeExportAllDeclaration + * @typedef {import('@typescript-eslint/types').TSESTree.ExportDefaultDeclaration} TSESTreeExportDefaultDeclaration + * @typedef {import('@typescript-eslint/types').TSESTree.ExportNamedDeclaration} TSESTreeExportNamedDeclaration + */ + module.exports = { meta: { type: 'problem', @@ -23,7 +29,22 @@ module.exports = { /** @param {RuleContext} context */ create(context) { /** @param {ExportAllDeclaration | ExportDefaultDeclaration | ExportNamedDeclaration} node */ - function report(node) { + function verify(node) { + const tsNode = + /** @type {TSESTreeExportAllDeclaration | TSESTreeExportDefaultDeclaration | TSESTreeExportNamedDeclaration} */ ( + node + ) + if (tsNode.exportKind === 'type') { + return + } + if (tsNode.type === 'ExportNamedDeclaration') { + if ( + tsNode.specifiers.length > 0 && + tsNode.specifiers.every((spec) => spec.exportKind === 'type') + ) { + return + } + } context.report({ node, messageId: 'forbidden' @@ -31,9 +52,9 @@ module.exports = { } return utils.defineScriptSetupVisitor(context, { - ExportAllDeclaration: report, - ExportDefaultDeclaration: report, - ExportNamedDeclaration: report + ExportAllDeclaration: verify, + ExportDefaultDeclaration: verify, + ExportNamedDeclaration: verify }) } } diff --git a/package.json b/package.json index c2eefdb34..f3abcbcdb 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "@types/natural-compare": "^1.4.0", "@types/node": "^13.13.5", "@types/semver": "^7.2.0", - "@typescript-eslint/parser": "^5.0.0-0", + "@typescript-eslint/parser": "^5.4.0", "@vuepress/plugin-pwa": "^1.4.1", "acorn": "^8.5.0", "env-cmd": "^10.1.0", @@ -82,7 +82,7 @@ "mocha": "^7.1.2", "nyc": "^15.1.0", "prettier": "^2.4.1", - "typescript": "^4.4.3", + "typescript": "^4.5.0-0", "vue-eslint-editor": "^1.1.0", "vuepress": "^1.8.2" } diff --git a/tests/lib/rules/no-export-in-script-setup.js b/tests/lib/rules/no-export-in-script-setup.js index 5bc759f4c..3ea915401 100644 --- a/tests/lib/rules/no-export-in-script-setup.js +++ b/tests/lib/rules/no-export-in-script-setup.js @@ -8,6 +8,7 @@ // Requirements // ------------------------------------------------------------------------------ +const semver = require('semver') const eslint = require('eslint') const rule = require('../../../lib/rules/no-export-in-script-setup') @@ -48,7 +49,43 @@ ruleTester.run('no-export-in-script-setup', rule, { let foo; ` - } + }, + ...(semver.gte( + require('@typescript-eslint/parser/package.json').version, + '5.4.0' + ) && + semver.satisfies(require('typescript/package.json').version, '>=4.5.0-0') + ? [ + { + filename: 'test.vue', + code: ` + + `, + parser: require.resolve('vue-eslint-parser'), + parserOptions: { + parser: require.resolve('@typescript-eslint/parser') + } + } + ] + : [ + { + filename: 'test.vue', + code: ` + + `, + parser: require.resolve('vue-eslint-parser'), + parserOptions: { + parser: require.resolve('@typescript-eslint/parser') + } + } + ]) ], invalid: [ @@ -102,6 +139,34 @@ ruleTester.run('no-export-in-script-setup', rule, { line: 8 } ] + }, + { + filename: 'test.vue', + code: ` + + `, + parser: require.resolve('vue-eslint-parser'), + parserOptions: { + parser: require.resolve('@typescript-eslint/parser') + }, + errors: [ + { + message: '`