strict 严格模式详解:TypeScript-New-Handbook 之 noImplicitAny 与 strictNullChecks
【免费下载链接】TypeScript-New-HandbookIncubation repository for the new TypeScript handbook 🐣项目地址: https://gitcode.com/gh_mirrors/ty/TypeScript-New-Handbook
如果你正在学习 TypeScript,那么strict 严格模式一定是你绕不开的第一道门槛。作为新 TypeScript 手册(TypeScript-New-Handbook)中最核心的编译选项之一,strict就像一把"类型检查总开关",开启后能自动帮你揪出大量潜在 bug。本文将用最通俗的方式,为你详细拆解noImplicitAny与strictNullChecks这两个最关键的开关,手把手教你如何开启它们、理解它们,并真正用起来。
🎯 什么是 strict 严格模式:类型检查的"总开关"
很多新手第一次接触 TypeScript 时会有这样的困惑:"我明明写了类型,为什么代码还是能随便乱传值?" 答案往往就藏在strict这个开关里。
简单来说,strict是一个总开关:把它设为true,就等同于同时开启了一整套"严格模式家族"检查项,包括:
| 检查项 | 作用 |
|---|---|
noImplicitAny | 禁止隐式any类型 |
strictNullChecks | 严格检查null与undefined |
strictFunctionTypes | 严格检查函数类型 |
strictBindCallApply | 严格检查bind/call/apply |
strictPropertyInitialization | 严格检查类属性初始化 |
在 TypeScript-New-Handbook 的官方手册中(见 chapters/Basics.md),作者给出了一个很形象的比喻:严格模式就像把类型检查从一个"开关"变成了一个"旋钮",旋钮拧得越高,TypeScript 替你检查得就越多。只要条件允许,新项目都应该开启 strict 严格模式。
📌 项目参考:本文内容主要来自仓库中的 chapters/Basics.md 与 chapters/Everyday Types.md,相关编译选项的完整说明可查阅 reference/Compiler Options.md。
🔧 noImplicitAny 详解:如何消灭隐式 any
noImplicitAny 是什么意思?
先说背景:TypeScript 有一个非常"宽松"的特殊类型any,它表示"任意类型"。当代码里某个值无法推断出具体类型时,TypeScript 会默认把它当作any——这在某些时候很方便,但也会让你失去类型检查的全部保护。
noImplicitAny的作用就是:凡是 TypeScript 只能"默默猜成 any"的地方,直接报错提醒你,而不是让你在不知不觉中失去保护。来看一个手册中的经典例子:
function greet(person, date) { console.log(`Hello ${person}, today is ${date}!`); } // 开启 noImplicitAny 后,person 和 date 会报"隐式 any"错误是不是很眼熟?这种"忘写参数类型"的代码,在开启noImplicitAny后会立刻被高亮提示,逼着你把类型补上。虽然在 chapters/Everyday Types.md 中提到,any类型本身"并不是最坏的情况",但类型标注越完整,你能获得的智能提示和错误检查就越多。
一键开启 noImplicitAny 的方法
在tsconfig.json中这样配置即可:
{ "compilerOptions": { "noImplicitAny": true } }当然,更推荐的做法是直接开启strict,因为noImplicitAny本来就是它的一部分:
{ "compilerOptions": { "strict": true } }🚫 strictNullChecks 详解:告别 "xxx is not a function"
如果说noImplicitAny解决的是"类型太宽松"的问题,那么strictNullChecks解决的就是**"空值危机"**——也就是那句让无数前端程序员崩溃的报错:TypeError: Cannot read properties of null。
开启前后的巨大差别
TypeScript 手册在 chapters/Everyday Types.md 中用很直白的话解释了两者的区别:
- 关闭时:
null和undefined可以赋值给任何类型的变量,访问任何可能为空的属性都不报错。这虽然"写起来省事",但正是无数 bug 的温床。 - 开启时:
null和undefined拥有自己独立的类型,你不能在没有检查的情况下直接使用它们。想用?先判断!
function doSomething(x: string | null) { if (x === null) { // 处理空值的情况 } else { console.log("Hello, " + x.toUpperCase()); // 安全! } }这种"先判断、后使用"的模式,在 TypeScript 中叫作窄化(Narrowing),手册 chapters/Narrowing.md 对此有专门的深入讲解。配合可选属性(?),strictNullChecks还能帮你发现"某个对象属性可能没定义"的隐患——详见 chapters/Object Types.md。
遇到"我确定它不为空"怎么办?
有时候你比编译器更清楚某个值一定存在,此时可以使用非空断言运算符!:
function liveDangerously(x?: number | null) { console.log(x!.toFixed()); // 告诉 TypeScript:x 一定不是 null }⚠️ 注意:
!不会改变代码运行时的行为,它只是"骗过"类型检查。请务必只在确信值不可能为空时使用,否则就是给自己埋雷。
⚙️ 完整开启 strict 严格模式:最省心的配置方法
说了这么多,其实真正实践起来非常简单。新建项目时,在tsconfig.json里加上一行就搞定:
{ "compilerOptions": { "strict": true } }开启之后你会得到:
- ✅ 参数、变量不会被偷偷当成
any - ✅
null与undefined必须显式处理 - ✅ 函数类型、类属性初始化也一并被严格检查
- ✅ 编辑器中获得更准确的代码补全与错误提示
💡 小技巧:如果老项目一次性开启strict报错太多,也可以先只开noImplicitAny或strictNullChecks中的一个,分阶段迁移,再逐步加上其他开关。手册 reference/Compiler Options.md 中特别提醒:strict家族未来还可能会加入新的检查项,升级 TypeScript 版本时请留意新增的报错。
🤔 常见问题 FAQ
Q1:不开启 strict 严格模式,能学 TypeScript 吗?当然能。但手册明确建议:新代码库应始终开启这些严格检查,因为它能帮你少踩无数坑。
Q2:strictNullChecks 和 noImplicitAny 必须一起开吗?不是必须,它们是两个独立选项,可以分别开启或关闭。但一起开(即直接strict: true)效果最好。
Q3:开启 strict 后报错太多怎么办?先别慌,把报错当成"编译器免费送的体检报告"。优先修复noImplicitAny相关的隐式any,再逐个处理null/undefined的判断,代码质量会肉眼可见地提升。
📝 总结
strict严格模式是 TypeScript 最值得信赖的"安全气囊",而noImplicitAny与strictNullChecks正是其中最核心的两个组成部分:
- noImplicitAny:让隐式
any无处遁形,逼你写出更完整的类型; - strictNullChecks:让
null和undefined不再"偷偷混入"你的代码,从源头消灭空值崩溃。
如果你想深入钻研,非常推荐通读 TypeScript-New-Handbook 仓库中的 chapters/Basics.md(类型基础与严格模式总览)、chapters/Everyday Types.md(any与null/undefined详解)以及 chapters/Narrowing.md(窄化技巧),配合 reference/Compiler Options.md 查阅全部编译选项。从今天起,给你的tsconfig.json加上"strict": true,让 TypeScript 帮你把好每一道关吧!🚀
【免费下载链接】TypeScript-New-HandbookIncubation repository for the new TypeScript handbook 🐣项目地址: https://gitcode.com/gh_mirrors/ty/TypeScript-New-Handbook
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考