TypeScript 非空断言怎么用
如果你写代码时经常遇到“可能有值也可能没值”的情况,大概率会见过 TypeScript 报的“对象可能为 undefined”这类错误。比如你想从 localStorage 里取用户存的名字,写localStorage.getItem('username'),TypeScript 会说这个返回值可能是null,不能直接用。这时候就需要用到“非空断言”——简单说就是跟 TypeScript 拍板:“这个值我保证是存在的,别跟我纠结了”。
---

先搞懂:什么时候需要非空断言?
举个日常例子:你点外卖填收货地址,页面上有个“小区名称”输入框,正常来说用户肯定会填,你从 DOM 里拿这个输入框的元素,写document.getElementById('address'),TypeScript 会告诉你这个方法可能返回null,万一用户没填就空提交呢?
这时候如果确定元素一定存在,就可以用非空断言。它的写法很简单,就是在值后面加一个感叹号!,比如document.getElementById('address')!。相当于你跟 TypeScript 说:“这个元素我保证肯定能拿到,不用检查空值”。
---
实际用例:帮你避开常见的场景
从 localStorage 取确定存在的数据
比如你之前写代码时,已经保证过 localStorage 里有theme这个键,不会删它,就可以这么写:
`typescript
// 之前存过,肯定有值,不用 TypeScript 再啰嗦
const theme = localStorage.getItem('theme')!;
`
如果不用这个感叹号,你就得加判断if (theme) { ... },但你已经确定有,写!能省点代码。
取 DOM 元素时确定存在
刚才说的收货地址输入框,如果你知道页面上肯定有这个 ID 的元素:
`typescript
// 页面上一定有这个输入框,不用怕 null
const addressInput = document.getElementById('address')! as HTMLInputElement;
// 现在可以直接取输入值了
console.log(addressInput.value);
`
这里多了个as HTMLInputElement是顺便做了类型断言,因为 getElementById 默认返回HTMLElement,加这个告诉 TypeScript 这是个输入框,能取value。
初始化后肯定赋值的变量
比如你定义了一个变量,先声明,后面再赋值,确定后面一定会给值:
`typescript
let userName!: string; // 声明就加!,说明后续一定赋值
// 后面异步接口返回后赋值
fetch('/api/user').then(res => res.json()).then(data => {
userName = data.name;
});
// 这里调用 userName,TypeScript 不会报错,因为你保证后面赋值了
`
---
划重点:非空断言不是“免错金牌”
很多新手刚用这个感叹号,容易踩坑——它只瞒 TypeScript,不瞒浏览器。如果你本来应该有值的地方,实际是空的,比如 localStorage 里的theme被用户手动删了,你用了!,运行时就会报Cannot read property 'xxx' of null的错误。
举个反面例子:你写代码时偷懒,没判断就拿输入框的值:
`typescript
// 万一页面上输地址的输入框被误删了,运行就报错
const address = document.getElementById('address')!.value;
`
所以非空断言的核心前提是:你100%确定这个值绝对不会是null或undefined,不能把它当“忽略错误”的工具。
---
总结一下
TypeScript 的非空断言,就是用!告诉编译器“这个值肯定非空”,适合用在你已经做过保证的场景:比如确定 localStorage 的键存在、确定 DOM 元素不会缺失、确定变量后续会赋值。它能帮你少写点冗余的判断代码,但别乱用——如果对值的存在性没把握,还是老老实实加个空判断,不然最后出了运行bug,可没人帮你背锅。