← 返回题目列表

tsconfig 中 strict 模式有什么作用?

高频 中等 第 7 / 32 题 更新于 2026/07/27
TypeScripttsconfigstrict

简化版

strict 是 TypeScript 的严格类型检查总开关,开启后会启用一组更严格的规则,比如 strictNullChecksnoImplicitAnystrictFunctionTypes 等。它能提前发现更多潜在错误,但迁移老项目时可能需要逐步开启。

详细版

常见严格选项:

  • noImplicitAny:不允许隐式 any。
  • strictNullChecksnull/undefined 不再随便赋给其他类型。
  • strictFunctionTypes:更严格检查函数参数兼容。
  • strictPropertyInitialization:类属性必须初始化。

strictNullChecks 很重要:

function f(name?: string) {
  // name.toUpperCase(); // 可能 undefined
  return name?.toUpperCase();
}

严格模式能让空值、隐式 any、未初始化属性等问题在编译期暴露。

完整版教学

一、strict 不是单个规则

strict: true 会打开一组规则。随着 TS 版本演进,strict 包含的检查可能增加,因此它代表更强的类型安全姿态。

新项目建议直接开启。老项目如果历史 any 很多,可以分阶段治理。

二、noImplicitAny 防止类型黑洞

如果参数没有类型,TS 推不出来时会给 any。隐式 any 很危险,因为它会绕过后续检查。

function add(a, b) {
  return a + b;
}

开启 noImplicitAny 后,必须显式声明或让 TS 能推断。

三、strictNullChecks 提升空值安全

不开启时,nullundefined 可以赋给很多类型,容易运行时报错。开启后,你必须明确处理空值。

这会让代码多一些判断,但线上空指针问题会少很多。

四、迁移策略

老项目可以先开启部分规则,比如 noImplicitAny,再处理 strictNullChecks。也可以对边界层使用 unknown 和类型守卫,逐步收窄。

不要为了通过编译到处写 as any,那相当于把问题藏起来。

五、面试追问与工程落地

strict 常见追问是“老项目能不能直接全开”。现实中不一定。全开可能一下暴露几千个错误,阻塞业务迭代。更合理的是分模块、分选项逐步开启,新增代码严格,老代码逐步偿还类型债。

还会问 strict 是否会影响运行时性能。TypeScript 类型检查发生在编译期,类型本身会被擦除,严格模式不会让运行时代码变慢。它影响的是开发阶段的检查力度和迁移成本。

工程里要警惕用 as any// @ts-ignore 快速压错。短期能过编译,长期会把类型系统打穿。更好的做法是补准确类型、收窄 unknown、封装边界适配层。

六、按风险分层迁移,而不是机械消除报错

strict 是一组严格家族选项的总开关,并允许单独关闭某个子项。TypeScript 后续版本可能把新的检查纳入 strict,因此升级编译器后出现新错误并不等于运行时代码突然变化,而是静态分析覆盖面扩大。迁移前应固定编译器版本并记录错误基线。

{
  "compilerOptions": {
    "strict": true,
    "useUnknownInCatchVariables": true,
    "noUncheckedIndexedAccess": true
  }
}

后两个选项适合严格工程,但要注意 noUncheckedIndexedAccess 并不是 strict 家族自动开启的选项。假设老项目有 1000 个类型错误,可以先按边界输入、空值、函数兼容、类初始化四类统计,再以模块为单位把错误数从 1000 降到 700、300、0;不要用 1000 个 as any 把仪表盘瞬间清零。

选项主要防护常见迁移代价
noImplicitAny隐式类型黑洞补参数和第三方声明
strictNullChecks空值误用补联合类型与分支判断
strictFunctionTypes不安全参数兼容调整回调签名;方法语法有例外
strictPropertyInitialization类字段未初始化构造器赋值或明确初始化策略

strictFunctionTypes 主要更严格地检查函数语法的参数位置,方法语法为兼容常见层级结构保留了较宽松行为。面试中把它简单说成“所有函数参数都完全逆变”会遗漏这个现实边界。

严格迁移的目标是恢复真实类型关系,而不是让错误计数归零;所有 suppress 注释都应有原因、范围和清理计划。

七、常见误区与追问

  • 误区:strict 只是 strictNullChecks 的别名。 它会开启一组严格家族选项,空值检查只是其中一项。
  • 误区:开启 strict 会让生产 JavaScript 运行更慢。 类型检查主要发生在编译期,类型会被擦除;成本集中在开发、检查和迁移阶段。
  • 误区:strict 会自动开启所有名字里带严格含义的选项。 noUncheckedIndexedAccess 等增强选项不属于 strict 家族,需要单独配置。
  • 追问:为什么升级 TypeScript 后 strict 项目会新增错误? 新版本可能扩展 strict 的检查行为或改进控制流分析,应结合发布说明评估。
  • 追问:老项目应该先开哪个选项? 没有唯一顺序,通常先做错误基线和边界隔离,再选择收益高且改动可控的规则分模块推进。
  • 追问:strictFunctionTypes 检查所有方法吗? 它对函数语法更严格,但方法声明存在兼容性例外,不能用一个结论覆盖全部写法。
  • 追问:可以用 skipLibCheck 解决业务错误吗? 它主要跳过声明文件内部检查,不会修复业务源码类型关系,也不应替代依赖版本治理。

八、加强记忆

strict 模式是 TS 的“安全带”。它会让你写代码时麻烦一点,但能把很多空值、隐式 any、未初始化问题提前暴露出来。

迁移时把报错当成风险清单逐类消化,而不是用断言抹掉,strict 才真正形成工程收益。