Skip to main content

类型化检查

编辑器 ESLint 报告已过时文件更改后

¥Editor ESLint reports become out-of-date after file changes

至少在 VS Code 中,类型化 linting 存在一个已知问题,即在多次更新磁盘上的文件后,文件可能会出现过时的 lint 错误。根本原因是 ESLint 没有为编辑器提供了解跨文件依赖(例如类型信息)的方法。这会导致文件在导入的文件发生更改时接收过时的类型信息。

¥There is a known issue in at least VS Code with typed linting that files might have out-of-date lint errors after multiple updates to files on disk. The root cause is that ESLint doesn't provide a way for editors to know about cross-file dependencies, such as type information. This results in files receiving out-of-date type information when files they import from are changed.

你可能会将此视为对 anyerror typed 值的错误 no-unsafe-* 规则投诉。其他规则可能更微妙地不正确。

¥You might see this as erroneous no-unsafe-* rule complaints on any or error typed values. Other rules may be more subtly incorrect.

目前,解决方法是在类型过期时在 VS Code 中运行 Restart ESLint Server 命令(或其他编辑器中的等效命令)。

¥For now, the workaround is to run the Restart ESLint Server command in VS Code (or an equivalent in other editors) when types get out of date.

有关更多信息,请参阅 ESLint 不重新计算文件更改的跨文件信息 (microsoft/vscode-eslint#1774)

¥See ESLint does not re-compute cross-file information on file changes (microsoft/vscode-eslint#1774) for more information.

如何禁用文件的类型检查 linting?

¥How do I disable type-checked linting for a file?

使用 ESLint 的配置对象 和我们的 disable-type-checked 配置来禁用包含该文件的 files 匹配的类型检查。

¥Use ESLint's configuration objects with our disable-type-checked config to disable type checking for a files match that includes that file.

例如,要禁用所有 .js 文件上的类型检查 linting:

¥For example, to disable type-checked linting on all .js files:

eslint.config.mjs
import tseslint from 'typescript-eslint';

export default tseslint.config(
// ... the rest of your config ...
{
files: ['**/*.js'],
extends: [tseslint.configs.disableTypeChecked],
},
);

或者,要手动禁用文件的类型检查,你可以将 parserOptions: { project: false } 设置为要排除的文件的覆盖。

¥Alternatively to disable type checking for files manually, you can set parserOptions: { project: false } to an override for the files you wish to exclude.

如何禁用一组文件的类型感知 linting?

¥How can I disable type-aware linting for a set of files?

你可以将 ESLint 的 overrides 配置与我们的 disable-type-checked 配置结合起来,以关闭特定文件子集上的类型感知 linting。

¥You can combine ESLint's overrides config in conjunction with our disable-type-checked config to turn off type-aware linting on specific subsets of files.

eslint.config.mjs
export default tseslint.config(
eslint.configs.recommended,
tseslint.configs.recommendedTypeChecked,
tseslint.configs.stylisticTypeChecked,
{
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
},
{
files: ['**/*.js'],
extends: [tseslint.configs.disableTypeChecked],
},
);
信息

如果你使用其他插件的类型感知规则,则需要手动禁用这些规则或使用它们提供的预制配置来禁用它们。

¥If you use type-aware rules from other plugins, you will need to manually disable these rules or use a premade config they provide to disable them.

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

¥typescript-eslint thinks my variable is never nullish / is any / etc., but that is clearly not the case to me

我们的类型感知规则几乎总是信任 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 还显示该类型从不为空/是 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 possibly 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.

是否支持 TypeScript 项目引用?

¥Are TypeScript project references supported?

是的,但仅限于 parserOptions.projectService

¥Yes, but only with parserOptions.projectService.

请参阅 问题 #2094 讨论项目引用 以了解更多详细信息。

¥See issue #2094 discussing project references for more details.

项目服务问题

¥Project Service Issues

parserOptions.projectService 是从 typescript-eslint v8 开始启用类型 linting 的推荐解析器选项。它强制项目从编辑器(如 VS Code)使用的相同 tsconfig.json 文件生成类型化 linting 的类型信息。

¥parserOptions.projectService is the recommended parser option to enable typed linting as of typescript-eslint v8. It enforces projects generate type information for typed linting from the same tsconfig.json files used by editors such as VS Code.

我收到错误,告诉我“...项目服务未找到。考虑将其包含在 tsconfig.json 中或包含在 allowDefaultProject 中”

¥I get errors telling me "... was not found by the project service. Consider either including it in the tsconfig.json or including it in allowDefaultProject"

这些错误是由于尝试使用项目服务对未明确包含在其最近的 tsconfig.json 中的文件进行 lint 而导致的。

¥These errors are caused by attempting to use the project service to lint a file not explicitly included in its nearest tsconfig.json.

项目服务将尝试使用磁盘上距离该文件最近的 tsconfig.json 为每个正在 lint 的文件构建类型信息。如果该 tsconfig.json 不包含该文件,并且该文件未在 allowDefaultProject 中列入允许列表,则项目服务将抛出此错误。

¥The project service will attempt to build type information for each file being linted using the nearest tsconfig.json on disk to that file. If that tsconfig.json does not include the file, and the file isn't allowlisted in allowDefaultProject, then the project service will throw this error.

对于每个正在报告的文件:

¥For each file being reported:

另请注意:

¥Note also:

  • TSConfigs 默认不包含 .js 文件。要执行此操作,必须启用 allowJscheckJs

    ¥TSConfigs don't include .js files by default. Enabling allowJs or checkJs is required to do so.

  • 项目服务只查看 tsconfig.json 文件。它不查看 tsconfig.eslint.json 或其他名称相似的文件。

    ¥The project service only looks at tsconfig.json files. It does not look at tsconfig.eslint.json or other coincidentally-similarly-named files.

如果这些步骤对你不起作用,请 在 typescript-eslint 的 typescript-estree 包上提交问题 告诉我们你的用例以及为什么你需要更多项目外文件进行 linted。请务必包含我们可以使用的最小复制品,以了解你的用例!

¥If these steps don't work for you, please file an issue on typescript-eslint's typescript-estree package telling us your use case and why you need more out-of-project files linted. Be sure to include a minimal reproduction we can work with to understand your use case!

我收到错误消息,告诉我 "众所周知,使用默认项目运行许多文件会导致性能问题并减慢 linting 速度。"

¥I get errors telling me "Having many files run with the default project is known to cause performance issues and slow down linting."

这些错误是由于尝试使用项目服务对其 allowDefaultProject 选项未明确包含在 tsconfig.json 中的太多文件进行 lint 而导致的。

¥These errors are caused by attempting to use the project service to lint too many files not explicitly included in a tsconfig.json with its allowDefaultProject option.

typescript-eslint 默认允许最多 8 个 "项目之外" 文件。每个文件都会导致为其包含的每个文件构建一个新的 TypeScript "program",这会给每个文件带来性能开销。

¥typescript-eslint allows up to 8 "out of project" files by default. Each file causes a new TypeScript "program" to be built for each file it includes, which incurs a performance overhead for each file.

对于每个正在报告的文件:

¥For each file being reported:

我想使用 tsconfig.json 以外的 TSConfigs 来获取项目服务类型信息

¥I'd like to use TSConfigs other than tsconfig.jsons for project service type information

allowDefaultProject 中用于 "项目之外" 文件的 TSConfig 路径可以自定义。否则,只会读取磁盘上的 tsconfig.json 文件。

¥Only the TSConfig path used for "out of project" files in allowDefaultProject can be customized. Otherwise, only tsconfig.json files on disk will be read.

例如,而不是:

¥For example, instead of:

  • tsconfig.json 用于构建(巧合的是,编辑器中的类型信息)

    ¥tsconfig.jsons for building (and, coincidentally, type information in editors)

  • 将 TSConfig(s) 分离为 tsconfig.eslint.json 以便进行 linting

    ¥Separate TSConfig(s) like tsconfig.eslint.json for linting

考虑使用:

¥Consider using:

  • tsconfig.json 用于 linting(并且,有意地,编辑器中的相同类型信息)

    ¥tsconfig.jsons for linting (and, intentionally, the same type information in editors)

  • 将 TSConfig(s) 分离为 tsconfig.build.json 以便进行构建

    ¥Separate TSConfig(s) like tsconfig.build.json for building

项目服务使用与 VS Code 等编辑器相同的底层 TypeScript 逻辑。仅使用 tsconfig.json 进行类型检查会强制要求编辑器中看到的类型与用于检查的类型相匹配。

¥The project service uses the same underlying TypeScript logic as editors such as VS Code. Using only tsconfig.json for typed linting enforces that the types seen in your editor match what's used for linting.

传统项目问题

¥Traditional Project Issues

我收到错误,告诉我“ESLint 已配置为运行...但是,该 TSConfig 不包含/这些 TSConfig 均不包含此文件”

¥I get errors telling me "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.

修复错误

¥Fixing the Error

  • 如果你不想使用 lint 文件:

    ¥If you do not want to lint the file:

  • 如果你确实想使用 lint 文件:

    ¥If you do want to lint the file:

    • 如果你不想使用 类型感知的 linting 来 lint 文件:

      ¥If you do not want to lint the file with type-aware linting:

    • 如果你确实想使用 类型感知的 linting 来 lint 文件:

      ¥If you do want to lint the file with type-aware linting:

      • 检查你提供给 parserOptions.project 的每个 TSConfig 的 include 选项 - 你必须确保所有文件都与 include glob 匹配,否则我们的工具将无法找到它。

        ¥Check the include option of each of the TSConfigs that you provide to parserOptions.project - you must ensure that all files match an include glob, or else our tooling will not be able to find it.

        • 如果文件是 .cjs.js.mjs 文件,请确保启用了 allowJs

          ¥If the file is a .cjs, .js, or .mjs file, make sure allowJs is enabled.

      • 如果你的文件不应该成为你现有 tsconfigs 之一的一部分(例如,它是 repo 本地的脚本/工具),那么请考虑在你的项目根目录中创建一个新的 tsconfig(我们建议将其称为 tsconfig.eslint.json),并在其 include 中列出此文件。例如,你可以查看我们之前在此 repo 中使用的配置:

        ¥If your file shouldn't be a part of one of your existing tsconfigs (for example, it is a script/tool local to the repo), then consider creating a new tsconfig (we advise calling it tsconfig.eslint.json) in your project root which lists this file in its include. For an example of this, you can check out the configuration we previously used in this repo:

更多细节

¥More Details

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

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

  • 源文件的 ESLint 配置在 parserOptions.project 中指定至少一个 TSConfig 文件

    ¥The ESLint configuration for the source file specifies at least one TSConfig file in parserOptions.project

  • 这些 TSConfig 文件都不包含正在检查的源文件

    ¥None of those TSConfig files includes the source file being linted

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

  • 带有 parserOptions.project: true.eslintrc.cjs / eslint.config.mjs

    ¥An .eslintrc.cjs / eslint.config.mjs with parserOptions.project: true

  • 带有 include: ["src"]tsconfig.json

    ¥A tsconfig.json with include: ["src"]

在这种情况下,使用 ESLint 扩展在 IDE 中查看文件将显示错误通知,提示该文件无法被 linting,因为它不包含在 tsconfig.json 中。

¥In that case, viewing the file 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.

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

¥I get errors telling me "The file must be included in at least one of the projects provided"

你正在使用过时的 @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.

我可以自定义用于项目的 TSConfig 吗?

¥Can I customize the TSConfig used for the project?

是的,但在大多数配置中不推荐使用。parserOptions.projectService 使用与 VS Code 等编辑器相同的 "项目服务" API 来生成 TypeScript 的类型信息。使用不同的 TSConfig 可能会为类型化 linting 提供与编辑器或 tsc 看到的不同的类型。

¥Yes, but it's not recommended in most configurations. parserOptions.projectService uses the same "project service" APIs used by editors such as VS Code to generate TypeScript's type information. Using a different TSConfig runs the risk of providing different types for typed linting than what your editor or tsc see.

如果绝对必须,可以使用 parserOptions.project 选项代替 parserOptions.projectService

¥If you absolutely must, the parserOptions.project option can be used instead of parserOptions.projectService with either:

  • true:始终使用最接近源文件的 tsconfig.json

    ¥true: to always use tsconfig.jsons nearest to source files

  • string | string[]:任意数量的 glob 路径,用于匹配相对于 parserOptions.tsconfigRootDir 的 TSConfig 文件,或者如果未提供当前工作目录,则匹配当前工作目录

    ¥string | string[]: any number of glob paths to match TSConfig files relative to parserOptions.tsconfigRootDir, or the current working directory if that is not provided

例如,如果你使用特定的 tsconfig.eslint.json 进行 linting,则应指定:

¥For example, if you use a specific tsconfig.eslint.json for linting, you'd specify:

eslint.config.mjs
export default tseslint.config({
// ...
languageOptions: {
parserOptions: {
project: './tsconfig.eslint.json',
tsconfigRootDir: import.meta.dirname,
},
},
// ...
});

参见 有关更多详细信息,请参阅 @typescript-eslint/parser project 文档

¥See the @typescript-eslint/parser project docs for more details.

注意

如果你的项目是多包 monorepo,请参阅 故障排除 > 类型 Linting > Monorepos

¥If your project is a multi-package monorepo, see Troubleshooting > Typed Linting > Monorepos.