TypeScript与ESlint

静态程序分析工具在代码运行之前对代码进行分析检查,能够发现代码中存在的缺陷,并有助于提高代码的质量。

本节将介绍适用于 TypeScript 的静态程序分析工具 ESLint,它几乎成了 TypeScript 程序的标准配置。我们将通过一个示例来演示如何在 TypeScript 工程中启用 ESLint 工具。

ESLint

ESLint 是一个适用于 JavaScript 语言的静态程序分析工具。

ESLint 依据预定义的一组规则来检查代码,当发现代码中违反了某项规则时给出相应提示。例如,ESLint 中有一个名为 “eqeqeq” 的规则,该规则要求代码中必须进行严格相等性比较,即必须使用 “===” 和 “!==” 运算符,而不允许使用 “==” 和 “!=” 运算符。当发现代码中使用了 “==” 或 “!=” 运算符时将给出提示信息。

2019年,TypeScript 开发团队决定采用 ESLint 作为 TypeScript 源码的静态分析工具。同时,TypeScript 开发团队也对 ESLint 进行了扩展,使其能够检查 TypeScript 源码。此外,TypeScript 开发团队还为 ESLint 增加了一些专用于 TypeScript 语言的检查规则。例如:

  • 是否允许使用三斜线指令?

  • 是否允许命名接口时使用某个前缀?比如 IAnimal 中使用大写字母 “I” 作为接口前缀。

实例演示

本节中,将通过一个简单的例子来演示如何将 TypeScript 与 ESLint 结合使用。与配置 Babel 的前四步相同,我们需要安装 Node.js 和 TypeScript,并且初始化工程。

假设当前项目的目录结构如下:

C:\ts-eslint
|-- node_modules
|   `-- typescript
|-- src
|   `-- index.ts
|-- package.json
|-- package-lock.json
`-- tsconfig.json

package.json 文件的内容如下:

{
    "name": "ts-eslint",
    "version": "1.0.0",
    "devDependencies": {
        "typescript": "^3.8.2"
    }
}

tsconfig.json 文件的内容如下:

{
    "compilerOptions": {
        "target": "ES6",
        "strict": true,
        "outDir": "dist"
    }
}

安装ESLint

在 “C:\ts-eslint” 目录下,运行如下命令来安装 ESLint 及相关工具:

npm install --save-dev eslint \
                       @typescript-eslint/parser \
                       @typescript-eslint/eslint-plugin

此时,“C:\ts-eslint” 目录的结构如下:

C:\ts-eslint
|-- node_modules
|   |-- <省略了一部分代码包>
|   |-- @typescript-eslint
|   `-- eslint
|-- src
|   `-- index.ts
|-- package.json
|-- package-lock.json
`-- tsconfig.json

配置ESLint

配置 ESLint 的常用方式是使用 ESLint 配置文件。ESLint 配置文件的文件名为 “.eslintrc.*” 的形式。它支持多种文件格式,如 JavaScript、JSON 和 YAML 等。此例中,我们将使用 JSON 格式的 ESLint 配置文件。

在 “C:\ts-eslint” 目录下新建一个 .eslintrc.json 文件,该文件的内容如下:

{
    "root": true,
    "parser": "@typescript-eslint/parser",
    "plugins": ["@typescript-eslint"],
    "extends": [
        "eslint:recommended",
        "plugin:@typescript-eslint/eslint-recommended",
        "plugin:@typescript-eslint/recommended"
    ],
    "rules": {
        "no-console": "warn",
        "@typescript-eslint/array-type": [
            "error",
            {
                "default": "generic"
            }
        ]
    }
}

该配置文件中包含了一些核心的配置项,下面我们依次介绍它们。

“root” 属性定义了该配置文件是否为根配置文件。在默认情况下,ESLint 会查找并使用所有父级目录下的配置文件,并且父级目录下的配置文件具有更高的优先级。若某个配置文件中的 “root” 属性为 true,那么 ESLint 在搜索到该配置文件后将不再继续向上查找父级目录下的配置文件。

“parser” 属性定义了代码解析器。如果检查的是 JavaScript 代码,那么可以忽略该选项,因为 ESLint 内置了对 JavaScript 的支持。由于我们想要检查 TypeScript 代码,因此需要将该选项设置为 “@typescript-eslint/parser”。“@typescript-eslint/parser” 是专为 TypeScript 语言定制的代码解析器,只有配置了该代码解析器,ESLint 才能够理解 TypeScript 代码。

“plugins” 属性定义了使用的 ESLint 插件,它能够扩展 ESLint 的功能。此例中,我们使用了 “@typescript-eslint” 插件,该插件提供了为 TypeScript 定制的代码检查规则,例如前面提到的 “是否允许使用三斜线指令” 检查规则。只有在 “plugins” 属性中添加了对应的插件,我们才能够使用该插件里定义的代码检查规则。

“extends” 属性定义了继承的检查规则。此例中,

  • “eslint:recommended” 包含了 ESLint 推荐的内置检查规则。例如,它推荐使用严格相等比较运算符 “===” 和 “!==”。

  • “plugin:@typescript-eslint/eslint-recommended” 禁用了一部分 “eslint:recommended” 中提供的规则,因为 TypeScript 编译器已经能够检查这些规则,所以不必进行重复的检查。

  • “plugin:@typescript-eslint/recommended” 包含了 “@typescript-eslint” 插件提供的推荐的检查规则。

“rules” 属性中定义了针对于单个检查规则的详细配置。此例中 ,我们详细配置了两个检查规则:

  • “no-console”,当代码中调用了 console 对象上的方法时给出警告,例如“console.log()”。

  • “@typescript-eslint/array-type”,该规则来自 “@typescript-eslint” 插件,它要求 TypeScript 代码中的数组类型注解使用泛型形式 “Array<T>” 而不是 “T[]”。当代码违反了该规则时会报错,因为我们指定了 “error” 参数。

此时,“C:\ts-eslint” 目录的结构如下:

C:\ts-eslint
|-- node_modules
|   |-- <省略了一部分代码包>
|   |-- @typescript-eslint
|   `-- eslint
|-- src
|   `-- index.ts
|-- .eslintrc.json
|-- package.json
|-- package-lock.json
`-- tsconfig.json

配置忽略的文件

通常情况下,不是工程中所有的代码都需要进行静态分析检查,例如在 “node_modules” 目录下安装的第三方文件和某些测试文件是不需要进行静态检查的。在默认情况下,ESLint 会检查工程中所有的代码,但是可以使用 “.eslintignore” 文件来配置忽略检查的文件。

在 “C:\ts-eslint” 目录下新建一个 “.eslintignore” 文件,且该文件的内容如下:

node_modules
dist

此例中,ESLint 会忽略 “C:\ts-eslint\node_modules” 目录下和 “C:\ts-eslint\dist” 目录下的代码。

现在,“C:\ts-eslint” 目录的结构如下:

C:\ts-eslint
|-- node_modules
|   |-- <省略了一部分代码包>
|   |-- @typescript-eslint
|   `-- eslint
|-- src
|   `-- index.ts
|-- .eslintignore
|-- .eslintrc.json
|-- package.json
|-- package-lock.json
`-- tsconfig.json

运行ESLint

接下来,让我们对 index.ts 文件稍做修改来制造一些错误,修改后的 index.ts 文件的内容如下:

const a: number[] = [0];

console.log(a);

在 “C:\ts-eslint” 目录下运行 eslint 命令来检查 TypeScript 代码,示例如下:

npx eslint . --ext .ts

eslint 命令的运行结果如下:

C:\ts-eslint\src\index.ts
    1:10  error    Array type using 'number[]' is forbidden. Use 'Array<number>'
        instead  @typescript-eslint/array-type
    3:1   warning  Unexpected console statement
        no-console

x 2 problems (1 error, 1 warning)
 1 error and 0 warnings potentially fixable with the `--fix` option.

此例中,ESLint 检查出 index.ts 中的代码违反了以下两个规则:

  • 第 1 行,禁止使用 “number[]”,应该替换为 “Array<number>”,违反的规则为 “@typescript-eslint/array-type”。

  • 第 3 行,使用了禁用的 “console” 语句。

在输出结果的最后一行,ESLint 还提示了可以使用 “--fix” 选项来自动修复其中一个错误,即 “number[]” 的使用错误。在 “C:\ts-eslint” 目录下运行 eslint 命令并使用 “--fix” 选项来修复该错误,示例如下:

npx eslint . --ext .ts --fix

在运行该命令后,index.ts 将会被修改为如下内容:

const a: Array<number> = [0];

console.log(a);

我们能够看到,第 1 行中的格式错误已经被自动修正,但是第 3 行的警告则无法被自动修复。

集成 Visual Studio Code

我们已经介绍了如何为工程添加 ESLint 静态代码检查。ESLint 也能够与大部分集成开发环境(IDE)和构建工具进行集成。例如:

  • Visual Studio Code

  • Sublime Text

  • Gulp

  • Webpack

接下来,将介绍如何在 Visual Studio Code 中使用 ESLint。

安装ESLint插件

在 Visual Studio Code 中,打开上一节创建的项目,如图9-5所示。

image 2024 02 08 00 11 13 280
Figure 1. 图9-5 在Visual Studio Code中打开工程

出现图9-6的界面,打开插件应用市场(见图9-6中);在搜索框中输入 “ESLint”(见图9-6中);选择 ESLint 插件(见图9-6中);点击 “Install” 按钮来安装 ESLint 插件(见图9-6中)。

image 2024 02 08 00 12 19 968
Figure 2. 图9-6 安装插件

图9-7所示为成功地安装并自动启用了 ESLint 插件。

image 2024 02 08 00 12 52 591
Figure 3. 图9-7 安装成功

查看静态检查错误

在安装了 ESLint 插件后,Visual Studio Code 能够实时地对代码进行静态类型检查。对于代码中存在的静态检查错误,Visual Studio Code 会在代码下面显示红色的波浪线(见图9-8中);对于代码中存在的静态检查警告,Visual Studio Code 会在代码下面显示黄色的波浪线。此外,Visual Studio Code 还会在 “Problems” 面板中显示静态检查的消息列表(见图9-8中)。

image 2024 02 08 00 13 47 984
Figure 4. 图9-8 查看静态检查错误

自动修复静态检查错误

将鼠标光标移动到存在问题的代码上时会显示一个提示框(见图9-9中)。

image 2024 02 08 00 14 26 206
Figure 5. 图9-9 显示问题提示框

点击 “Quick Fix …​” 会显示可选的修复选项列表,选择 “Fix all auto-fixable problems” 即可自动修复代码(见图9-10中)。

image 2024 02 08 00 15 05 968
Figure 6. 图9-10 显示可选的修复选项列表

修复后的代码如图9-11所示,Visual Studio Code 只会修复能够被自动修复的问题。

image 2024 02 08 00 15 37 982
Figure 7. 图9-11 修复后的代码

小结

TypeScript 能够与 ESLint 完美地结合,它们都有助于提高代码的质量。使用 ESLint 能够保证代码使用了一致的编码风格,从而增加了代码可读性。例如,ESLint 能够检查是否使用了一致的代码缩进。除了编码风格之外,ESLint 也能够检查代码中是否存在潜在的错误,例如是否使用了严格相等比较等。TypeScript 能够根据代码的静态类型信息做进一步的检查。TypeScript 和 ESLint 的检查范围没有一个明确的界限,而实际上两者的功能的确有一部分重合,但是这并不影响正常使用。在项目中,我们应该使用 ESLint 或者类似的代码静态分析工具,就算使用最基本的检查规则也能够受益颇多。