tslint 配置不是简单的规则开关,而是一套围绕代码规范、团队协作和工程效率的动态治理方案,核心答案:以可共享配置为基底,用 overrides 按场景差异化覆盖,再配合 pre-commit 钩子强制落地。
为什么你的 tslint 配置总在“打架”
很多前端团队都经历过这样的场景:后端同事提交的 TypeScript 代码里混着四个空格缩进,而前端组坚持两个空格;老项目里允许 console.log 到处飞,新项目却要求一律移除,问题不在于谁的规则更正确,而在于 tslint 配置没有按项目、按目录、按文件类型做分层管理,写配置文件前,先想清楚三个问题:这份配置服务的是单一仓库还是多包工程?包与包之间是否需要不同规范?历史遗留代码是立即整改还是渐进迁移? 想清楚之后,再看具体怎么写。
如何设计一套分层 tslint 配置
先看最小可用结构,假设你的项目根目录长这样:
project/ ├── tslint.json ├── src/ │ ├── app/ │ ├── shared/ │ └── utils/ ├── scripts/ └── test/
根目录的 tslint.json 只做三件事:继承基础规则、定义全局禁用项、声明 overrides 分块,具体操作路径如下:
第一步:选准基础配置
社区里常用的基础包有 tslint:recommended、tslint-config-airbnb、codelyzer(Angular 专用),行业共识认为,没有银弹配置,按框架选型定基础即可,React 项目用 Airbnb 风格,Angular 项目必须引入 codelyzer 的规则集。但注意,基础包里的规则不一定都符合你的工程实际,所以接下来要逐条检查。
第二步:用 overrides 拆解差异化场景
这是 tslint 配置的核心技巧,写法如下:
{

"extends": ["tslint:recommended"],
"rules": {
"quotemark": [true, "single", "avoid-escape"],
"semicolon": [true, "always"],
"no-console": [true, "log", "error"]
},
"overrides": [
{
"files": ["src//.spec.ts"],
"rules": {
"no-console": false,
"quotemark": [true, "double"]
}
},
{
"files": ["scripts//.ts"],
"rules": {
"no-console": false,
"no-var-requires": false
}
}
]
}
这段配置的含义很直白:测试文件允许 console,但必须用双引号;工具脚本允许 require 和 console,如果没有 overrides,你就得在测试文件里写一排 // tslint:disable-next-line,丑且难维护,tslint 中还有一种场景,比如某个遗留模块正在重构,你可以单独给 legacy/ 目录关闭 typedef 规则,等到重构完成再删掉 override。
第三步:处理规则间的冲突
常见冲突例如 ordered-imports 要求 import 按字母排序,但 eslint-plugin-import 的规则可能要求按路径深度排序,在 tslint 配置阶段,直接用 "ordered-imports": [false] 关闭其一,保持 lint 规则与编辑器自动修复逻辑一致即可,另一个高频冲突是 object-literal-key-quotes 与 prettier 的 quoteProps 设置,把两个工具都指向“必要时才加引号”就不会打架。
tslint 与编辑器、构建流程的协同配置
配置写在 json 里只是第一步,真正让团队跑起来的是编辑器统一和 CI 拦截。
VS Code 里的最优实践
首先安装 tslint 插件,然后在 settings.json 里设置:
{
"typescript.tsdk": "node_modules/typescript/lib",
"tslint.autoFixOnSave": true,
"tslint.alwaysShowRuleFailures": true,
"editor.formatOnSave": false
}
注意 autoFixOnSave 只在保存时修复安全规则,比如分号、引号、多余空格,对于需要手工决策的规则(no-console),插件会划红线提醒,不自动处理。请在你的项目 README 里统一写明这三行配置,否则新同事入职第一周就会出现代码风格漂移。

利用预提交钩子强制拦截
推荐使用 lint-staged + husky,配合 tslint 实现“改哪些文件就查哪些文件”,具体命令链是:
npx mrm lint-staged
# 在 package.json 里配置:
# "lint-staged": { ".ts": ["tslint --fix", "git add"] }
这样每次提交前,只有暂存区里的 .ts 文件会被检查,改动范围小,检查速度快。如果配置里有 --project 参数,请确保 tsconfig.json 路径正确,否则 rules 里依赖类型信息的规则(如 no-unused-variable)会失效。
tslint 常见报错排查与配置优化
实际开发中,大家问的最多的是三类问题,先看报错表格:
| 报错信息 | 触发原因 | 配置建议 |
|---|---|---|
| “Type ‘X’ has no properties in common with type ‘Y’” | strict 模式过严 | 临时降级为 allow 或关闭对应接口检查规则 |
| “Forbidden ‘var’ keyword” | no-var 规则开启 | 保留,但用 overrides 放行第三方类型声明 |
| “文件超过 line-length” | 行宽限制 | 要么改代码,要么在特定文件关掉该规则 |
排查时不要急着 tslint --fix,先看规则文档里该条规则的“Requires type information”字段。凡是需要类型信息的规则,必须在 tslint.json 里配置 "linterOptions": { "typeCheck": true } 或者用 --project 运行,否则会静默失效,不少团队发现“为什么我开了 no-any 但 any 还是随便用”,十有八九就是没开类型检查。
优化技巧是给规则加“严重度”。"no-empty": { "severity": "warning" },这样它只出现在输出里而不会阻塞构建,渐进式重构老项目时,把未来要修复的规则全部设成 warning,既能看到问题又不影响编译,等清完 warning 再切回 error。
从 tslint 迁移到 ESLint 的配置对照思路
虽然 tslint 已进入维护模式,但 2026 年仍有大量存量项目在使用它,如果你接手的是老项目,现在需要把 tslint 配置移植到 ESLint,核心是理解两者规则的映射关系,对照表如下:

| tslint 规则 | ESLint 对应规则 | 迁移难点 |
|---|---|---|
| quotemark | quotes | 需要处理 avoid-escape 参数 |
| ordered-imports | import/order | 组别设置不同,需重排 |
| member-access | @typescript-eslint/explicit-member-accessibility | 默认值有差异 |
| no-unused-variable | @typescript-eslint/no-unused-vars | 需要配置 argsIgnorePattern |
迁移时不要逐条抄规则,而是根据你们团队的实际报告来筛选。把 tslint 里的 warning 项作为重点硬性规则迁移,把 error 项按可自动修复程度排序,优先迁移能自动修复的规则,可以显著减少人工改动量。
Q&A:tslint配置常见问题速查
tslint 和 eslint 能同时配置吗?
技术上可以用两套配置并跑,但会带来重复检查和规则冲突,建议用 @typescript-eslint 插件替代 tslint,如果因为历史依赖暂时不能移除,可以在 tslint 配置里用 "extends" 外部包减少维护量,并通过 eslintConfig 的 overrides 让两套工具各管一部分,ESLint 管 JS 文件,tslint 只管 ts 文件。
为什么我配置了 no-console 但打包时还是会输出 log?
先确认你的 tslint 是否真正运行到了目标文件,用 npx tslint -c tslint.json 'src//.ts' 手动执行一次,看是否有报错,如果用了 webpack 的 ts-loader,需要把 transpileOnly: true 改为 false 或使用 fork-ts-checker-webpack-plugin,让 tslint 在编译前执行,最后检查 no-console 的写法,[true, "log"] 只禁止 console.log,而 [true, "log", "error"] 会连 console.error 一起禁止,通常建议保留 error 输出,只禁 log。
tslint 配置里路径通配符 与 的区别是什么?
匹配当前目录下的文件,不递归子目录; 递归匹配任意层级的子目录。src/.ts 只匹配 src 根目录下的 ts 文件,src//.ts 匹配 src 下所有层级的 ts 文件,书写 overrides 的 files 字段时,尽量用 精确到你希望覆盖的目录层级,test//.spec.ts,避免误伤同名文件。
