Skip to content

Commit

Permalink
Fix false positives for script setup with ts (#1976)
Browse files Browse the repository at this point in the history
* Fix false positives for script setup with ts

* fix test for ts eslint v4
  • Loading branch information
ota-meshi authored Sep 16, 2022
1 parent b1f1432 commit 30b1471
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 30 deletions.
24 changes: 23 additions & 1 deletion lib/rules/no-undef-components.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,29 @@ module.exports = {
(scope) => scope.type === 'module'
)
for (const variable of (moduleScope && moduleScope.variables) || []) {
if (variable.isTypeVariable) {
if (
// Check for type definitions. e.g. type Foo = {}
(variable.isTypeVariable && !variable.isValueVariable) ||
// type-only import seems to have isValueVariable set to true. So we need to check the actual Node.
(variable.defs.length > 0 &&
variable.defs.every((def) => {
if (def.type !== 'ImportBinding') {
return false
}
if (def.parent.importKind === 'type') {
// check for `import type Foo from './xxx'`
return true
}
if (
def.node.type === 'ImportSpecifier' &&
def.node.importKind === 'type'
) {
// check for `import { type Foo } from './xxx'`
return true
}
return false
}))
) {
scriptTypeOnlyNames.add(variable.name)
} else {
scriptVariableNames.add(variable.name)
Expand Down
111 changes: 82 additions & 29 deletions tests/lib/rules/no-undef-components.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

const RuleTester = require('eslint').RuleTester
const rule = require('../../../lib/rules/no-undef-components')
const semver = require('semver')

const tester = new RuleTester({
parser: require.resolve('vue-eslint-parser'),
Expand Down Expand Up @@ -598,6 +599,26 @@ tester.run('no-undef-components', rule, {
<script setup>
import TheModal from 'foo'
</script>`
},
{
filename: 'test.vue',
code: `
<script setup lang="ts">
import Foo from './Foo.vue'
import {HelloWorld1} from './components/HelloWorld'
</script>
<template>
<Foo />
<HelloWorld1 />
</template>
`,
parserOptions: {
ecmaVersion: 6,
sourceType: 'module',
parser: require.resolve('@typescript-eslint/parser')
},
parser: require.resolve('vue-eslint-parser')
}
],
invalid: [
Expand Down Expand Up @@ -661,9 +682,14 @@ tester.run('no-undef-components', rule, {
}
]
},
{
filename: 'test.vue',
code: `
...(semver.gte(
require('@typescript-eslint/parser/package.json').version,
'5.0.0'
)
? [
{
filename: 'test.vue',
code: `
<script setup lang="ts">
import type Foo from './Foo.vue'
import type {HelloWorld1} from './components/HelloWorld'
Expand All @@ -681,6 +707,58 @@ tester.run('no-undef-components', rule, {
<HelloWorld4 />
<HelloWorld5 />
</template>
`,
parserOptions: {
ecmaVersion: 6,
sourceType: 'module',
parser: require.resolve('@typescript-eslint/parser')
},
parser: require.resolve('vue-eslint-parser'),
errors: [
{
message:
"The '<Foo>' component has been used, but 'Foo' only refers to a type.",
line: 12
},
{
message:
"The '<HelloWorld1>' component has been used, but 'HelloWorld1' only refers to a type.",
line: 13
},
{
message:
"The '<HelloWorld2>' component has been used, but 'HelloWorld2' only refers to a type.",
line: 14
},
{
message:
"The '<HelloWorld3>' component has been used, but 'HelloWorld3' only refers to a type.",
line: 15
},
{
message:
"The '<HelloWorld4>' component has been used, but 'HelloWorld4' only refers to a type.",
line: 16
},
{
message:
"The '<HelloWorld5>' component has been used, but 'HelloWorld5' only refers to a type.",
line: 17
}
]
}
]
: []),
{
filename: 'test.vue',
code: `
<script setup lang="ts">
type Foo = {}
</script>
<template>
<Foo />
</template>
`,
parserOptions: {
ecmaVersion: 6,
Expand All @@ -692,32 +770,7 @@ tester.run('no-undef-components', rule, {
{
message:
"The '<Foo>' component has been used, but 'Foo' only refers to a type.",
line: 12
},
{
message:
"The '<HelloWorld1>' component has been used, but 'HelloWorld1' only refers to a type.",
line: 13
},
{
message:
"The '<HelloWorld2>' component has been used, but 'HelloWorld2' only refers to a type.",
line: 14
},
{
message:
"The '<HelloWorld3>' component has been used, but 'HelloWorld3' only refers to a type.",
line: 15
},
{
message:
"The '<HelloWorld4>' component has been used, but 'HelloWorld4' only refers to a type.",
line: 16
},
{
message:
"The '<HelloWorld5>' component has been used, but 'HelloWorld5' only refers to a type.",
line: 17
line: 7
}
]
},
Expand Down
1 change: 1 addition & 0 deletions typings/eslint-plugin-vue/util-types/ast/es-ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ export interface ImportSpecifier extends HasParentNode {
type: 'ImportSpecifier'
imported: Identifier
local: Identifier
importKind?: 'type' | 'value'
}
export interface ImportDefaultSpecifier extends HasParentNode {
type: 'ImportDefaultSpecifier'
Expand Down

0 comments on commit 30b1471

Please sign in to comment.