为啥 Eslint 在 .vue 文件中看不到全局 TypeScript 类型(no-undef)
Posted
技术标签:
【中文标题】为啥 Eslint 在 .vue 文件中看不到全局 TypeScript 类型(no-undef)【英文标题】:Why Eslint don't see global TypeScript types in .vue files (no-undef)为什么 Eslint 在 .vue 文件中看不到全局 TypeScript 类型(no-undef) 【发布时间】:2021-07-29 21:52:26 【问题描述】:我的 Vue/TypeScript 项目中有一个全局类型。在.ts
文件中,一切正常,Eslint 看到了,但在.vue
文件中,Eslint 抛出类型未定义的错误。 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/typings.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 |
【问题讨论】:
因为这种类型没有declare
?
@EstusFlask,我尝试declare module
,但没有帮助。我认为如果是这种情况,则不会在 .ts
文件中定义类型
【参考方案1】:
troubleshooting documentation of typescript-eslint has an entry 关于这个:
no-undef lint 规则不使用 TypeScript 来确定存在的全局变量 - 相反,它依赖于 ESLint 的配置。
我们强烈建议您不要在 TypeScript 项目中使用 no-undef lint 规则。它提供的检查已经由 TypeScript 提供,无需配置 - TypeScript 只是在这方面做得更好。
他们建议通过向您的 ESLint 配置添加覆盖来禁用 TypeScript 的 no-undef
,如下所示:
overrides: [
files: ['*.ts', '*.vue'],
rules:
'no-undef': 'off',
,
,
],
请注意,这会为所有 *.vue
文件禁用 no-undef
,无论它们使用 TypeScript 还是 javascript。
【讨论】:
以上是关于为啥 Eslint 在 .vue 文件中看不到全局 TypeScript 类型(no-undef)的主要内容,如果未能解决你的问题,请参考以下文章