为什么 Eslint 在 .vue 文件中看不到全局 TypeScript 类型(no-undef)



我的Vue/TypeScript项目中有一个全局类型。在.ts文件中,一切都很好,Eslint可以看到,但在.vue文件中,Eslind抛出未定义类型的错误。TypeScript没有抛出任何错误,并且看到了此类型。下面的配置和代码示例。

package.json

{
"dependencies": {
"@hse-design/core": "^1.1.0",
"@hse-design/vue": "^1.1.0",
"axios": "^0.21.1",
"cors": "^2.8.5",
"element-ui": "^2.12.0",
"faker": "^5.1.0",
"focus-visible": "^5.2.0",
"js-cookie": "^2.2.1",
"lodash": "^4.17.20",
"morgan": "^1.10.0",
"nprogress": "^0.2.0",
"path-to-regexp": "^6.2.0",
"register-service-worker": "^1.6.2",
"sanitize.css": "^12.0.1",
"vue": "^2.6.10",
"vue-class-component": "^7.2.6",
"vue-property-decorator": "^9.1.2",
"vue-router": "^3.1.2",
"vue-svgicon": "^3.2.6",
"vuex": "^3.1.1",
"vuex-class": "^0.3.2",
"vuex-module-decorators": "^1.0.1",
"yamljs": "^0.3.0"
},
"devDependencies": {
"@babel/plugin-proposal-optional-chaining": "^7.12.7",
"@babel/preset-typescript": "^7.13.0",
"@types/compression": "^1.7.0",
"@types/cors": "^2.8.8",
"@types/faker": "^5.1.4",
"@types/jest": "^26.0.21",
"@types/js-cookie": "^2.2.2",
"@types/lodash": "^4.14.165",
"@types/morgan": "^1.9.2",
"@types/node": "~14.14.35",
"@types/nprogress": "^0.2.0",
"@types/webpack-env": "^1.14.0",
"@types/yamljs": "^0.2.31",
"@typescript-eslint/eslint-plugin": "^4.22.1",
"@typescript-eslint/parser": "^4.22.1",
"@vue/cli-plugin-babel": "^4.5.12",
"@vue/cli-plugin-e2e-cypress": "^4.5.12",
"@vue/cli-plugin-eslint": "^4.5.12",
"@vue/cli-plugin-pwa": "^4.5.12",
"@vue/cli-plugin-typescript": "^4.5.12",
"@vue/cli-plugin-unit-jest": "^4.5.12",
"@vue/cli-service": "^4.5.12",
"@vue/eslint-config-standard": "^6.0.0",
"@vue/eslint-config-typescript": "^7.0.0",
"@vue/test-utils": "^1.0.0-beta.29",
"babel-core": "^7.0.0-bridge.0",
"babel-eslint": "^10.0.3",
"babel-loader": "^8.2.2",
"concurrently": "^6.0.0",
"core-js": "^3.12.0",
"eslint": "^7.25.0",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^4.3.1",
"eslint-plugin-standard": "^5.0.0",
"eslint-plugin-vue": "^7.9.0",
"fibers": "^5.0.0",
"jest": "^26.6.3",
"sass": "^1.22.10",
"sass-loader": "10.1.1",
"style-resources-loader": "^1.2.1",
"swagger-routes-express": "^3.2.1",
"ts-jest": "^26.5.4",
"ts-node-dev": "^1.0.0",
"typescript": "^4.2.3",
"vue-cli-plugin-element": "^1.0.1",
"vue-cli-plugin-style-resources-loader": "^0.1.3",
"vue-template-compiler": "^2.6.10",
"webpack": "^5.28.0"
}
}

tsconfig.json

{
"compilerOptions": {
"module": "ESNext",
"target": "ESNext",
"strict": true,
"jsx": "preserve",
"importHelpers": true,
"moduleResolution": "node",
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true,
"sourceMap": true,
"baseUrl": ".",
"types": [
"node",
"jest",
"webpack-env",
],
"typeRoots": [
"./src/@types",
"./node_modules/@types"
],
"paths": {
"@/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
},
"include": [ "src/**/*", "tests/**/*" ],
"exclude": [ "node_modules" ]
}

.eslint.js

module.exports = {
root: true,
env: {
browser: true,
node: true,
es6: true
},
parser: 'vue-eslint-parser',
parserOptions: {
parser: '@typescript-eslint/parser',
sourceType: 'module',
ecmaVersion: 2020
},
plugins: [
'vue'
],
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'class-methods-use-this': 0,
'consistent-return': 0,
'import/no-cycle': 0,
'import/extensions': 0,
'import/no-extraneous-dependencies': 0,
'space-before-function-paren': [2, 'never'],
'vue/array-bracket-spacing': 'error',
'vue/arrow-spacing': 'error',
'vue/block-spacing': 'error',
'vue/brace-style': 'error',
'vue/camelcase': 'error',
'vue/comma-dangle': 'error',
'vue/component-name-in-template-casing': 'error',
'vue/eqeqeq': 'error',
'vue/key-spacing': 'error',
'vue/match-component-file-name': 'error',
'vue/object-curly-spacing': 'error',
'vue/max-attributes-per-line': ['error', {
singleline: 3,
multiline: {
max: 1,
allowFirstLine: false
}
}]
},
extends: [
'eslint:recommended',
'airbnb-base',
'plugin:vue/recommended',
'@vue/standard',
'@vue/typescript'
]
}

src/@types/typeings.d.ts

type MyType = {
value: any
}

src/App.vue

<template>
<div id="app">
<router-view />
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'
@Component({
name: 'App',
})
export default class extends Vue {
myField: MyType = { value: 1 } // The error is here | Ошибка здесь
</script>

错误

error: 'MyType' is not defined (no-undef) at src/App.vue:15:12:
13 | })
14 | export default class extends Vue {
> 15 |   myField: MyType = { value: 1 }
|            ^
16 | }
17 | </script>
18 | 

typescript esint的故障排除文档中有一个条目:

无undef lint规则不使用TypeScript来确定存在的全局变量,而是依赖于ESLint的配置。

我们强烈建议您不要在TypeScript项目上使用无undef lint规则。它提供的检查已经由TypeScript提供,而无需配置——TypeScript只是做得更好。

他们建议通过在ESLint配置中添加覆盖来禁用TypeScript的no-undef,如下所示:

overrides: [
{
files: ['*.ts', '*.vue'],
rules: {
'no-undef': 'off',
},
},
],

请注意,这将禁用所有*.vue文件的no-undef,无论它们使用TypeScript还是JavaScript。

最新更新