tsgolint v7 稳定版:让 Oxlint 获得 Go 驱动的 TypeScript 类型感知检查

2026-09-11 28 预计阅读时间: 1 分钟
来源: infoq.com AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:9 分钟

TypeScript lint 的性能瓶颈,往往不在语法扫描,而在类型信息构建。只看 AST 的规则可以很快,但一旦规则需要判断 Promise 是否被处理、类型断言是否安全,或两个表达式在语义上是否兼容,就必须借助 TypeScript 编译器的语义分析。

tsgolint v7 已进入稳定阶段,它通过 typescript-go 编译器提供类型语义,并把这部分能力接入 Oxlint。Oxlint 继续负责配置解析和文件发现,tsgolint 则执行需要类型信息的规则。该版本兼容 TypeScript 7.0.2,并覆盖 61 条类型感知规则中的 59 条,目标是在保留语义检查能力的同时,显著降低相较 ESLint 类型检查链路的运行成本。

快速扫描和类型检查,终于可以明确分工

传统 TypeScript lint 工具通常在一个进程模型里完成文件发现、规则调度、AST 遍历和类型查询。项目规模增大后,构建类型图和反复访问编译器 API 会成为主要开销。

tsgolint 与 Oxlint 的组合采用了更清晰的职责划分:

  • Oxlint 读取配置、发现待检查文件,并承担常规 lint 工作。
  • tsgolint 处理必须依赖类型信息的规则。
  • typescript-go 提供 TypeScript 语义分析能力,让类型感知检查能够利用 Go 原生实现的性能特征。

这并不意味着每条 lint 规则都会突然变快。格式、命名、语法模式等规则本来就不需要类型系统;真正受益的是必须先理解程序语义才能判断的问题。把这类规则从常规扫描中区分出来,也方便团队在本地开发、提交检查和 CI 中采用不同策略。

59 条规则已经可用,但迁移不能只看数字

v7 实现了 61 条类型感知规则中的 59 条,覆盖率已经足以支撑大多数实际项目。不过,“支持 59 条”不等于可以把现有 ESLint 配置原样复制过来。

迁移时应逐项检查:

  1. 现有配置究竟启用了哪些类型感知规则。
  2. 剩余两条尚未覆盖的规则是否属于项目的强制质量门槛。
  3. 同名规则在边界输入、自动修复和报错位置上是否存在差异。
  4. monorepo 中的每个包能否找到正确的 tsconfig.json、项目引用和生成类型文件。
  5. 编辑器、提交钩子与 CI 是否使用了相同版本和相同入口。

稳定版意味着它更适合进入正式工程评估,但不代表迁移可以跳过基线对比。尤其是大量使用 project references、路径别名或生成代码的仓库,应先选一个包做影子运行。

可以这样搭建一个最小验证项目

下面的示例假设当前 Oxlint CLI 提供 --type-aware 入口,并使用 oxlint-tsgolint v7。运行前可执行 npx oxlint --help,确认安装版本的参数名称;如果项目锁定了不同版本,应以对应版本文档为准。

mkdir tsgolint-v7-demo
cd tsgolint-v7-demo
npm init -y
npm install --save-dev typescript oxlint oxlint-tsgolint@^7

cat > tsconfig.json <<'JSON'
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "strict": true,
    "noEmit": true
  },
  "include": ["src/**/*.ts"]
}
JSON

mkdir src
cat > src/index.ts <<'TS'
async function persistUser(name: string): Promise<void> {
  if (name.length === 0) {
    throw new Error("name is required");
  }
}

// 当项目启用相应的 Promise 类型感知规则时,这类调用应被检查。
persistUser("Ada");
TS

npx oxlint --type-aware .

这个项目的重点不是保证默认配置一定报告某条特定规则,而是验证三件事:CLI 能否启动类型感知模式、工具能否读取 tsconfig.json,以及 TypeScript 文件是否进入正确的语义分析链路。具体诊断结果取决于当前版本和项目启用的规则集合。

确认命令可用后,可以在 package.json 中把快速检查和类型检查拆开:

{
  "scripts": {
    "lint": "oxlint .",
    "lint:types": "oxlint --type-aware .",
    "lint:ci": "npm run lint && npm run lint:types"
  }
}

这种划分适合渐进式接入:开发者保存文件时运行快速 lint,提交前或 CI 再执行完整的类型感知规则。如果仓库规模不大,也可以直接把 lint:ci 作为统一入口。

性能评估要测自己的仓库

发布信息表明,tsgolint 相较 ESLint 展现出显著性能提升,但团队不应把别人的基准数字直接写进容量规划。lint 耗时还会受到文件数量、类型复杂度、磁盘缓存、monorepo 边界和 CI 机器规格影响。

可以用相同提交做一个简单的重复测量:

# 先预热依赖和文件缓存,再分别重复运行。
time npm run lint:types
time npm run lint:types

# 保留旧 ESLint 脚本时,用同一工作区和同一台机器比较。
time npm run lint:eslint
time npm run lint:eslint

除了总耗时,还应记录峰值内存、冷启动时间、增量修改后的耗时,以及诊断数量是否一致。速度更快但漏掉团队依赖的规则,并不是一次成功迁移。

建议采用双轨验证,而不是一次性替换

较稳妥的落地方式是让旧链路和新链路并行运行一段时间:

  • 固定 Oxlint、tsgolint 和 TypeScript 相关依赖版本,避免 CI 漂移。
  • 导出现有 ESLint 类型感知规则清单,与 59 条已支持规则逐项核对。
  • 先让 tsgolint 只生成报告,不立即阻塞合并。
  • 对比误报、漏报、诊断位置和执行时间。
  • 确认关键规则等价后,再把新链路提升为必过检查。
  • 暂时保留尚未覆盖的规则,必要时让 ESLint 只执行这部分规则。

v7 的意义不只是“用 Go 重写后更快”,而是让 Oxlint 从快速语法检查进一步进入 TypeScript 语义检查领域。对于被类型感知 lint 拖慢的中大型代码库,它值得尽快验证;但真正可靠的采用标准仍然是规则覆盖、诊断一致性和本仓库中的实际性能,而不是单独一个基准数字。


相关推荐