为啥 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)的主要内容,如果未能解决你的问题,请参考以下文章

我的全局变量在流星中看不到

为啥我在 Dev-C++ 中看不到项目文件?

Laravel mix 在 vue 组件中看不到 img 元素

为啥我在 XCode 项目中看不到我的构建阶段选项卡?

vue cli3及以上如何禁用eslint检查?

html小问题:网页中为啥有些内容在html源文件中看不到相应关键字?