! 非空断言

最后更新:2026-10-22

! 非空断言

非空断言(后缀 !)告诉编译器"这个值此刻肯定不是 null/undefined",把 T | null | undefined 收窄成 T。它不做任何运行时检查——值真是空的话,错误会在后续访问处才爆出来,所以要用在"你确实已经排除空值"的场合。

分组收窄与断言
类型操作符
严格模式不需要

ℹ️ 说明 编辑器将 TypeScript 转译为 JavaScript 后运行(不做类型检查);类型检查结果见示例 Output。

📝 语法

const el = document.getElementById("root")!;  // HTMLElement,而非 HTMLElement | null

const user = map.get("alice")!;                // User,而非 User | undefined
console.log(user.name);

⚙️ 参数

!后缀运算符,放在表达式后:仅从类型中移除 null 和 undefined,不产生任何运行时代码

返回值:无运行时效果——转译后 ! 完全消失;编译期只是从类型里去掉 null/undefined 成员。

▶ 示例

修改下面的代码,点击试一试查看转译运行结果:

输出:

100
no record

(转译后运行输出。aliceScore + 9 能通过类型检查是因为 ! 已收窄;若对 bob 也写 scores.get("bob")! + 1,编译通过但运行时得 NaN——! 不做任何检查)

💡 要点

⚠️ 注意 ! 是对编译器的口头保证,运行时零验证。判断错了不会立刻报错,而是在后续某个 .属性 访问处抛 TypeError,定位困难。能用 if (x) 或 ?? 兜底的场景优先用它们。
ℹ️ 说明 ! 只删除 null/undefined,不做其他收窄:string | number | null 写 x! 得到的是 string | number,不是 string。
💡 提示 几个公认合理的场景:getElementById 后确定元素存在;Map.set 之后再 get 同一键;测试代码里构造夹具。业务主流程里的成片 ! 是代码坏味道。
更多案例即将上线。

📚 相关教程

❓ 常见问题

Q ! 和 ?.(可选链)有什么区别?
A 方向相反:!.声称"肯定非空",空了照样炸;?. 承认"可能为空",为空时短路返回 undefined。防御性代码用 ?.,确定非空才用 !。
Q 关闭 strictNullChecks 后还需要 ! 吗?
A 不需要——null/undefined 可赋给任何类型,! 无事可做。这也是建议始终开 strictNullChecks 的原因之一:关掉它后 ! 变成纯噪音,空值错误全部转移到运行时。
Q 为什么很多团队在 ESLint 里禁用 !?
A 因为 ! 会静默吞掉空值风险,且随着代码重构(假设可能失效)不会像 if 检查那样给出编译错误。禁用后强制用守卫或 ??. 兜底,长期更安全。少数确有把握的场景用 eslint-disable 行级豁免。
Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏