TypeScript 类型检查
从类型系统、编译器、语言服务和 ESLint 的协作关系出发,理解 TypeScript 类型检查到底在检查什么、不在检查什么。
#dev
#typescript
#synthesis
#growing
[!info] related notes
- 所属 MOC: TypeScript MOC
- 总览页: TypeScript
- 相关概念: TypeScript 中的 strict, TypeScript 中的声明合并
- 相关调试: TypeScript 中 no-unsafe-declaration-merging 报错排查
- 相关工具: tsc, TypeScript 语言服务与 tsserver
TypeScript 类型检查
范围
这篇笔记讨论的是 TypeScript 类型检查的整体结构:它由哪些机制组成,哪些由 tsc 负责,哪些由语言服务负责,哪些又其实是 ESLint 在管。
为什么要放在一起理解
很多“TypeScript 报错”其实来源不同:
- 有的是类型系统本身的错误
- 有的是
tsconfig造成的项目边界问题 - 有的是编辑器语言服务给出的语义诊断
- 有的是
@typescript-eslint规则在报警
如果把它们都混成一种“TS 报错”,就很难判断该从哪里修。
依赖路径 / 调用链 / 演进链
一个典型的检查链条通常是:
- 代码被 TypeScript 类型系统解释
tsc或tsserver基于tsconfig构建 program- 类型错误、模块解析错误、声明文件错误被报告出来
- ESLint 再在类型信息之上叠加额外规则
也就是说,ESLint 里的部分 TypeScript 规则经常依赖 TypeScript 已经先把代码理解好了。
对比与易混淆点
TypeScript 类型检查 vs 运行时校验
- TypeScript:编译阶段保证“类型应该如何被理解”
- 运行时校验:处理外部数据是否真的满足这个结构
TypeScript 类型检查 vs ESLint
- TypeScript 负责类型语义
- ESLint 负责规则治理、风险模式和风格约束
比如 no-unsafe-declaration-merging 这类报错,表面上和 TypeScript 类型有关,但实际是 ESLint 在提示这段写法的维护风险。
编辑器红线 vs 命令行报错
两者不一定来自同一版本、同一上下文。先确认:
- 用的是哪一版 TypeScript
- 用的是哪个
tsconfig - 报错来自
tsc还是 ESLint
学习检查
不看正文回答:
- TypeScript 类型系统、tsc、tsserver、tsconfig、ESLint 各自在类型检查链路里承担什么?
- 为什么编辑器红线和命令行 tsc 结果可能不同?
- TypeScript 类型检查为什么不能验证网络 JSON 在运行时真的符合 interface?
- 模块解析错误、类型错误、lint rule violation 应怎样区分来源?
- 为什么部分 typescript-eslint 规则需要 TypeScript Program / 类型信息?
- 一个“IDE 报错但 CI 不报错”的案例,按 TS 版本、tsconfig、language service、ESLint 四层排查。