Skip to main content

故障排除和常见问题解答


我正在使用 ESLint 核心的规则,它无法与 TypeScript 代码一起正常工作

发生这种情况是因为 TypeScript 添加了 ESLint 不知道的新功能。

英:This happens because TypeScript adds new features that ESLint doesn't know about.

第一步是 请在此处查看我们的 "extension" 规则列表。 扩展规则是扩展基本 ESLint 规则以支持 TypeScript 语法的规则。 如果你在那里找到它,请尝试一下,看看它是否适合你。 你可以通过禁用基本规则并打开扩展规则来配置它。 以下是 semi 规则的示例:

英:The first step is to check our list of "extension" rules here. An extension rule is a rule which extends the base ESLint rules to support TypeScript syntax. If you find it in there, give it a go to see if it works for you. You can configure it by disabling the base rule, and turning on the extension rule. Here's an example with the semi rule:

{
"rules": {
"semi": "off",
"@typescript-eslint/semi": "error"
}
}

如果你找不到现有的扩展规则,或者扩展规则不适用于你的案例,那么你可以继续检查我们的问题。 贡献指南概述了提出问题的最佳方式

英:If you don't find an existing extension rule, or the extension rule doesn't work for your case, then you can go ahead and check our issues. The contributing guide outlines the best way to raise an issue.

我们每周都会发布新版本的工具。 请确保你 查看我们最新的 "extension" 规则列表 before 提交问题。

我收到错误消息,告诉我 "ESLint was configured to run ... However, that TSConfig does not / none of those TSConfigs include this file"

这些错误是由 ESLint 配置请求为未包含在 TypeScript 配置中的文件生成类型信息引起的。

英:These errors are caused by an ESLint config requesting type information be generated for a file that isn't included in the TypeScript configuration.

修复错误

  • 如果你 不要 想要检查文件:

  • 如果你 do 想要检查文件:

    • 如果你 不要 想使用 类型感知的 linting 对文件进行 lint 处理:

      • 使用 ESLint 的 overrides 配置 配置文件不被解析类型信息:

        一种流行的设置是从顶层配置中删除所有需要类型信息的规则,并仅通过覆盖将它们应用于 TypeScript 文件。
        .eslintrc.cjs
        module.exports = {
        // ... the rest of your config ...
        overrides: [
        {
        extends: [
        'plugin:@typescript-eslint/recommended-requiring-type-checking',
        ],
        files: ['./**/*.{ts,tsx}'],
        },
        ],
        };
        或者,在我们的 版本 v6 中,你可以使用我们的 disable-type-checked 配置 禁用针对该类型文件的类型检查。
        .eslintrc.cjs
        module.exports = {
        // ... the rest of your config ...
        overrides: [
        {
        extends: ['plugin:@typescript-eslint/disable-type-checked'],
        files: ['./**/*.js'],
        },
        ],
        };

        要手动禁用文件类型检查,请将 parserOptions: { project: null } 设置为你要排除的文件的覆盖。 请注意,{ project: undefined } 将不起作用,你还需要禁用任何需要类型检查的规则或规则选项。

    • 如果你 do 想使用 类型感知的 linting 对文件进行 lint 处理:

      • 检查你提供给 parserOptions.project 的每个 TSConfig 的 include 选项 - 你必须确保所有文件都与 include glob 匹配,否则我们的工具将无法找到它。
        • 如果文件是 .cjs.js.mjs 文件,请确保启用 allowJs
      • 如果你的文件不应该是现有 tsconfig 之一的一部分(例如,它是存储库本地的脚本/工具),请考虑在项目根目录中创建一个新的 tsconfig(我们建议将其称为 tsconfig.eslint.json),其中列出 该文件的 include。 有关示例,你可以查看我们在此存储库中使用的配置:

更多细节

此错误可能是由于以下两件事的结合而出现的:

英:This error may appear from the combination of two things:

  • 源文件的 ESLint 配置在 parserOptions.project 中指定至少一个 TSConfig 文件
  • 这些 TSConfig 文件都不包含正在检查的源文件

当指定 TSConfig 文件来解析源文件时,@typescript-eslint/parser 将使用第一个能够包含该源文件(根据 aka.ms/tsconfig#include)的 TSConfig 来生成类型信息。 但是,如果没有指定的 TSConfig 包含源文件,则解析器将无法生成类型信息。

英:When TSConfig files are specified for parsing a source file, @typescript-eslint/parser will use the first TSConfig that is able to include that source file (per aka.ms/tsconfig#include) to generate type information. However, if no specified TSConfig includes the source file, the parser won't be able to generate type information.

此错误最常发生在未包含在其项目 TSConfig 中的配置文件或类似文件上。 例如,许多项目都有如下文件:

英:This error most commonly happens on config files or similar that are not included in their project TSConfig(s). For example, many projects have files like:

  • .eslintrc.cjsparserOptions.project: ["./tsconfig.json"]
  • tsconfig.jsoninclude: ["src"]

在这种情况下,在具有 ESLint 扩展名的 IDE 中查看 .eslintrc.cjs 将显示错误通知,指出该文件无法进行 linted,因为它不包含在 tsconfig.json 中。

英:In that case, viewing the .eslintrc.cjs in an IDE with the ESLint extension will show the error notice that the file couldn't be linted because it isn't included in tsconfig.json.

有关更多信息,请参阅我们关于 类型感知 linting 的文档。

英:See our docs on type aware linting for more information.

我收到错误消息,告诉我 "该文件必须至少包含在所提供的项目之一中"

你使用的是过时版本的 @typescript-eslint/parser。 更新到最新版本以查看此错误消息的更多信息版本,解释了 above

英:You're using an outdated version of @typescript-eslint/parser. Update to the latest version to see a more informative version of this error message, explained above.

如何启用 @typescript-eslint 规则?

首先确保你已阅读文档并理解 ESLint 配置文件:

英:First make sure you've read the docs and understand ESLint configuration files:

我们的 规则文档 详细说明了 "选项" 标题下每个规则支持的选项。 我们使用 TypeScript 类型来描述规则的 Options 元组类型,你可以使用它来配置规则。 在你的配置文件中,rules 对象的键是你要配置的规则的名称,值遵循以下形式:

英:Our rule docs detail the options each rule supports under the "Options" heading. We use TypeScript types to describe an Options tuple type for the rule which you can use to configure the a rule. In your config file the keys of the rules object are the names of the rules you wish to configure and the values follow the following form:

type Severity = 'off' | 'warn' | 'error';
type RuleConfig =
| Severity
| [Severity]
| [
Severity,
// Options is the tuple type from the rule docs
...Options,
];

一些例子

英:Some examples

.eslintrc.js
module.exports = {
rules: {
// turns a rule on with no configuration (i.e. uses the default configuration)
'@typescript-eslint/array-type': 'error',
// turns on a rule with configuration
'@typescript-eslint/no-explicit-any': ['warn', { ignoreRestArgs: true }],
},
};

typescript-eslint 认为我的变量永远不会为空/是 any/等等,但对我来说显然不是这样

我们的类型感知规则几乎总是信任 TypeScript 编译器提供的类型信息。 因此,检查规则是否正确运行的一个简单方法是检查相关变量的类型,例如将鼠标悬停在 IDE 中的变量上。

英:Our type-aware rules almost always trust the type information provided by the TypeScript compiler. Therefore, an easy way to check if our rule is behaving correctly is to inspect the type of the variable in question, such as by hovering over it in your IDE.

如果 IDE 还显示该类型永远不会为 null / 为 any,则你需要修复该类型。 一个非常常见的情况是 no-unnecessary-condition 规则。 以这段代码为例:

英:If the IDE also shows that the type is never nullish / is any, you need to fix the type. A very common case is with the no-unnecessary-condition rule. Take this code for example:

let condition = false;

const f = () => (condition = true);
f();

if (condition) {
//^^^^^^^^^ Unnecessary conditional, value is always falsy.
}

通过在 IDE 中将鼠标悬停在 condition 上,你可以看到 condition 的类型实际上是字面量类型 false。 在这种情况下,typescript-eslint 不可能比 TypeScript 本身更了解,因此你需要通过修复类型来修复报告,例如通过断言(let condition = false as boolean)。

英:You can see that the type of condition is actually the literal type false by hovering over it in your IDE. In this case, typescript-eslint cannot possible know better than TypeScript itself, so you need to fix the report by fixing the type, such as through an assertion (let condition = false as boolean).

如果 IDE 提供的类型信息与 typescript-eslint 的报告不同,请确保用于你的 IDE、typescript-eslint 和 tsc 的 TypeScript 设置相同: 相同的 TypeScript 版本、相同的类型检查编译器选项以及项目中包含的相同文件。 例如,如果在另一个文件中声明了类型,但未包含该文件,则该类型将变为 any,并导致我们的 no-unsafe-* 规则报告。

英:If the IDE provides different type information from typescript-eslint's report, then make sure that the TypeScript setup used for your IDE, typescript-eslint, and tsc are the same: the same TypeScript version, the same type-checking compiler options, and the same files being included in the project. For example, if a type is declared in another file but that file is not included, the type will become any, and cause our no-unsafe-* rules to report.

我使用需要自定义文件扩展名的框架(如 Vue),并且收到类似 "你应该将 parserOptions.extraFileExtensions 添加到你的配置中" 的错误

你可以使用 parserOptions.extraFileExtensions 指定允许的非 TypeScript 扩展数组,例如:

英:You can use parserOptions.extraFileExtensions to specify an array of non-TypeScript extensions to allow, for example:

.eslintrc.js
module.exports = {
parserOptions: {
tsconfigRootDir: __dirname,
project: ['./tsconfig.json'],
extraFileExtensions: ['.vue'],
},
};

我在解析 .vue 文件中的 TypeScript 时遇到错误

如果你在解析 .vue 文件时遇到问题,可能是因为需要像 vue-eslint-parser 这样的解析器来解析 .vue 文件。 在这种情况下,你可以将 @typescript-eslint/parser 移到 parserOptions 内并使用 vue-eslint-parser 作为顶层解析器。

英:If you are running into issues parsing .vue files, it might be because parsers like vue-eslint-parser are required to parse .vue files. In this case you can move @typescript-eslint/parser inside parserOptions and use vue-eslint-parser as the top level parser.

- "parser": "@typescript-eslint/parser",
+ "parser": "vue-eslint-parser",
"parserOptions": {
+ "parser": "@typescript-eslint/parser",
"sourceType": "module"
}

parserOptions.parser 选项还可以指定一个对象来指定多个解析器。 有关详细信息,请参阅 vue-eslint-parser 使用指南

英:The parserOptions.parser option can also specify an object to specify multiple parsers. See the vue-eslint-parser usage guide for more details.

我的 lint 规则之一在纯 JavaScript 文件上无法正常工作

这是可以预料的 - ESLint 规则不会故意检查文件扩展名,因为它会在使用非标准扩展名的环境中导致问题(例如,.vue.md 文件都可以包含要检查的 TypeScript 代码)。

英:This is to be expected - ESLint rules do not check file extensions on purpose, as it causes issues in environments that use non-standard extensions (for example, a .vue and a .md file can both contain TypeScript code to be linted).

如果你有一些纯 JavaScript 代码,你不想应用某些 lint 规则,那么你可以使用 ESLint 的 overrides 配置 来关闭某些规则,甚至可以根据 glob 模式更改解析器。

英:If you have some pure JavaScript code that you do not want to apply certain lint rules to, then you can use ESLint's overrides configuration to turn off certain rules, or even change the parser based on glob patterns.

我应该在转译的输出 JavaScript 文件上运行 ESLint 吗?

不。

英:No.

源 TypeScript 文件包含输出 JavaScript 文件的所有内容以及类型注释。 对输出 JavaScript 文件进行 linting 并没有什么好处。

英:Source TypeScript files have all the content of output JavaScript files, plus type annotations. There's no benefit to also linting output JavaScript files.

TypeScript 应安装在本地

确保你已在本地安装 TypeScript,即使用 npm install typescript,而不是 npm install -g typescript,或者使用 yarn add typescript,而不是 yarn global add typescript。 请参阅 #2041 了解更多信息。

英:Make sure that you have installed TypeScript locally i.e. by using npm install typescript, not npm install -g typescript, or by using yarn add typescript, not yarn global add typescript. See #2041 for more information.

如何禁止 <specific language feature>

ESLint 核心包含规则 no-restricted-syntax。 此通用规则允许你为要禁止的代码指定 selector,以及自定义错误消息。

英:ESLint core contains the rule no-restricted-syntax. This generic rule allows you to specify a selector for the code you want to ban, along with a custom error message.

你可以使用 AST 可视化工具,例如左侧栏上的 typescript-eslint 在线运行 > 选项 > AST Explorer,通过选择 ESTree 来帮助确定你想要禁止的 AST 的结构。

英:You can use an AST visualization tool such as typescript-eslint playground > Options > AST Explorer on its left sidebar by selecting ESTree to help in figuring out the structure of the AST that you want to ban.

例如,你可以使用以下配置之一禁止枚举(或某种变体):

英:For example, you can ban enums (or some variation of) using one of the following configs:

{
"rules": {
"no-restricted-syntax": [
"error",
// ban all enums
{
"selector": "TSEnumDeclaration",
"message": "My reason for not using any enums at all"
},

// ban just const enums
{
"selector": "TSEnumDeclaration[const=true]",
"message": "My reason for not using const enums"
},

// ban just non-const enums
{
"selector": "TSEnumDeclaration:not([const=true])",
"message": "My reason for not using non-const enums"
}
]
}
}

为什么我在 ESLint 输出中看不到 TypeScript 错误?

TypeScript 的编译器(或任何你的构建链)是专门设计和构建的,用于验证代码库的正确性。 Our tooling does not reproduce the errors that TypeScript provides, because doing so would slow down the lint run [1], and duplicate the errors that TypeScript already outputs for you.

英:TypeScript's compiler (or whatever your build chain may be) is specifically designed and built to validate the correctness of your codebase. Our tooling does not reproduce the errors that TypeScript provides, because doing so would slow down the lint run [1], and duplicate the errors that TypeScript already outputs for you.

相反,我们的工具存在于 augment TypeScript 的内置检查中,这些检查使用 lint 规则,这些规则以新的方式使用类型信息,而不仅仅是验证代码的运行时正确性。

英:Instead, our tooling exists to augment TypeScript's built in checks with lint rules that consume the type information in new ways beyond just verifying the runtime correctness of your code.

[1] - TypeScript computes type information lazily, so us asking for the errors it would produce from the compiler would take an additional ~100ms per file. 这听起来不是很多,但根据代码库的大小,lint 运行的时间很容易就会增加几秒到几分钟。

英:[1] - TypeScript computes type information lazily, so us asking for the errors it would produce from the compiler would take an additional ~100ms per file. This doesn't sound like a lot, but depending on the size of your codebase, it can easily add up to between several seconds to several minutes to a lint run.

即使没有 TypeScript 错误,我也从 no-undef 规则中收到有关未定义全局变量的错误

no-undef lint 规则不使用 TypeScript 来确定存在的全局变量 - 相反,它依赖于 ESLint 的配置。

英:The no-undef lint rule does not use TypeScript to determine the global variables that exist - instead, it relies upon ESLint's configuration.

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

英:We strongly recommend that you do not use the no-undef lint rule on TypeScript projects. The checks it provides are already provided by TypeScript without the need for configuration - TypeScript just does this significantly better.

从我们的 v4.0.0 版本开始,这也适用于类型。 如果你使用第 3 方包中的全局类型(即 @types 包中的任何内容),那么你将必须适当配置 ESLint 来定义这些全局类型。 例如; @types/react 中的 JSX 命名空间是你必须在 ESLint 配置中定义的全局第三方类型。

英:As of our v4.0.0 release, this also applies to types. If you use global types from a 3rd party package (i.e. anything from an @types package), then you will have to configure ESLint appropriately to define these global types. For example; the JSX namespace from @types/react is a global 3rd party type that you must define in your ESLint config.

请注意,对于包含 JavaScript 和 TypeScript 的混合项目,可以通过向 .eslintrc.cjs 添加 overrides 部分来单独针对 TypeScript 文件关闭 no-undef 规则(与任何规则一样):

英:Note, that for a mixed project including JavaScript and TypeScript, the no-undef rule (like any rule) can be turned off for TypeScript files alone by adding an overrides section to .eslintrc.cjs:

.eslintrc.cjs
module.exports = {
// ... the rest of your config ...
overrides: [
{
files: ['*.ts', '*.mts', '*.cts', '*.tsx'],
rules: {
'no-undef': 'off',
},
},
],
};

如果你选择保留 ESLint no-undef lint 规则,则可以使用 在 ESLint 配置中手动定义允许的 globals,和/或可以使用 预定义环境 (env) 配置 之一。

英:If you choose to leave on the ESLint no-undef lint rule, you can manually define the set of allowed globals in your ESLint config, and/or you can use one of the pre-defined environment (env) configurations.

如何检查安装了哪些版本?

如果你有我们工具的多个版本,可能会导致各种错误。 这是因为 ESLint 可能会根据运行方式每次运行加载不同的版本 - 导致不一致的 lint 结果。

英:If you have multiple versions of our tooling, it can cause various bugs for you. This is because ESLint may load a different version each run depending on how you run it - leading to inconsistent lint results.

在项目的根目录中安装我们的工具并不意味着只安装一个版本。 你的一个或多个依赖可能对我们的工具有自己的依赖,这意味着 npm/yarn 将另外安装该版本以供该包使用。 例如,react-scriptscreate-react-app 的一部分)依赖于我们的工具。

英:Installing our tooling in the root of your project does not mean that only one version is installed. One or more of your dependencies may have its own dependency on our tooling, meaning npm/yarn will additionally install that version for use by that package. For example, react-scripts (part of create-react-app) has a dependency on our tooling.

你可以使用以下命令检查项目中安装的版本:

英:You can check what versions are installed in your project using the following commands:

npm list @typescript-eslint/eslint-plugin @typescript-eslint/parser

如果你看到安装了多个版本,则必须使用 Yarn 解析 强制使用单一版本,或者必须降级根版本以匹配依赖版本。

英:If you see more than one version installed, then you will have to either use yarn resolutions to force a single version, or you will have to downgrade your root versions to match the dependency versions.

在这种情况下,最好的做法是等待你的依赖发布支持我们最新版本的新版本。

英:The best course of action in this case is to wait until your dependency releases a new version with support for our latest versions.

如何指定 TypeScript 版本/parserOptions.typescriptLocation

你不能,你也不想。

英:You can't, and you don't want to.

你应该使用与项目其余部分相同版本的 TypeScript 进行 linting。 TypeScript 版本通常在边缘情况下存在细微差异,这可能会导致 typescript-eslint 规则和编辑器信息之间出现矛盾的信息。 例如:

英:You should use the same version of TypeScript for linting as the rest of your project. TypeScript versions often have slight differences in edge cases that can cause contradictory information between typescript-eslint rules and editor information. For example:

  • @typescript-eslint/strict-boolean-expressions 可能正在使用 TypeScript 版本 X 进行操作,并认为变量是 string[] | undefined
  • TypeScript 本身可能是版本 X+1-beta 并认为变量是 string[]

详细信息请参见 问题评论

英:See this issue comment for more details.

在我的 IDE 中对其他文件进行 linting 时,不会反映对一个文件的更改

TL;dr: 重新启动 ESLint 服务器以强制更新。

当磁盘上的任意文件发生更改时,ESLint 目前没有任何方法告诉解析器(例如我们的解析器)。 这意味着如果你更改文件 B 导入的文件 A,它不会更新文件 B 的 lint 缓存 - 即使文件 B 的文本内容已更改。 有时,唯一的解决方案是完全重新启动 ESLint 编辑器扩展。

英:ESLint currently does not have any way of telling parsers such as ours when an arbitrary file is changed on disk. That means if you change file A that is imported by file B, it won't update lint caches for file B -- even if file B's text contents have changed. Sometimes the only solution is to restart your ESLint editor extension altogether.

请参阅 问题评论 了解更多信息。

英:See this issue comment for more information.

提示

VS Code 的 ESLint 扩展 提供 ESLint: Restart ESLint Server 操作。

我收到 no-unsafe-* 条关于跨文件更改的投诉

参见 对一个文件的更改不会反映在我的 IDE 中对其他文件进行 linting 中no-unsafe-argumentno-unsafe-assignmentno-unsafe-call 等规则通常会受到影响。

英:See Changes to one file are not reflected in linting other files in my IDE. Rules such as no-unsafe-argument, no-unsafe-assignment, and no-unsafe-call are often impacted.

" '<key>' 属性在 '<type>' 节点上已弃用。 请改用 '<key>'。" 警告

如果你看到此警告,则可能你正在使用尚未针对 typescript-eslint v6 进行更新的 ESLint 插件(或其他工具)。 确保你使用的是每个 ESLint 插件(和其他工具)的最新版本。

英:If you're seeing this warning, it's likely you're using an ESLint plugin (or other tooling) that hasn't been updated for typescript-eslint v6. Make sure you're using the latest versions of each of your ESLint plugins (and other tooling).

如果你使用了许多 ESLint 插件,并且已将每个插件更新到最新版本,并且你不确定此投诉来自哪一个,请尝试以下任一或全部:

英:If you've using many ESLint plugins, have updated each to their latest version, and you're not sure which one this complaint is coming from, try either or both of:

  • 使用 --trace-deprecation 运行(例如 npx cross-env NODE_OPTIONS=--trace-deprecation npm run lint
  • 一次禁用其中一半以缩小其所属插件的范围

然后确保每个插件都有一个 GitHub 问题,要求他们发布支持 typescript-eslint v6 的版本。

英:Then make sure each of those plugins has a GitHub issue asking that they release a version supporting typescript-eslint v6.

提示

对于在插件中更新 ESLint 规则但仍需要支持 typescript-eslint v5 的开发者: 如果新的属性键不存在,你可能需要 || 回退到旧的属性键:

英:For developers updating ESLint rules in plugins that still need to support typescript-eslint v5: you may need to || fall back to the old property key if the new one doesn't exist:

- node.typeParameters
+ node.typeArguments || node.typeParameters

有关更多上下文,请参阅 一些名为 typeParameters 而不是 typeArguments 的属性 问题和实现 修复:根据需要将 typeParameters 重命名为 typeArguments 拉取请求。

英:For more context, see the Some properties named typeParameters instead of typeArguments issue, and the implementing fix: rename typeParameters to typeArguments where needed pull request.

typescript-eslint v6 发布帖子 有关于 typescript-eslint v6 的更多信息。

英:The typescript-eslint v6 release post has more information on typescript-eslint v6.

我的 linting 感觉非常慢

如果你认为遇到性能问题,请参阅我们的 性能故障排除文档

英:If you think you're having issues with performance, see our Performance Troubleshooting documentation.

是否支持 TypeScript 项目引用?

不,尚不支持 TypeScript 项目引用。

英:No, TypeScript project references are not yet supported.

详细信息请参见 问题 #2094 讨论项目引用

英:See issue #2094 discussing project references for more details.