一、null 和 undefined 在 TS 中是什么?
在 TypeScript 里:
ts
null // 一个值,表示“空”
undefined // 一个值,表示“未定义”它们 既是值,也是类型:
ts
let a: null = null
let b: undefined = undefined二、关键前提:strictNullChecks
现在99% 项目都开启了:
json
{
"compilerOptions": {
"strict": true
}
}等价于:
json
{
"strictNullChecks": true
}开 / 关的本质区别
❌ 未开启(老项目)
ts
let s: string
s = null // ✅ 不报错
s = undefined // ✅ 不报错👉 极其危险,类型形同虚设
✅ 开启(现代 TS 项目,默认)
ts
let s: string
s = null // ❌
s = undefined // ❌结论:
null和undefined不再是所有类型的子类型
三、正确使用 null / undefined 的方式
1️⃣ 显式声明可空
ts
let s: string | null
let t: string | undefined
let u: string | null | undefinedts
s = null
t = undefined👉 必须用联合类型
2️⃣ 对象属性中的可选 vs undefined
可选属性 ?
ts
interface User {
name: string
age?: number
}等价于:
ts
age: number | undefined但不等价于 null
ts
const u1: User = { name: 'Tom' } // ✅
const u2: User = { name: 'Tom', age: 18 } // ✅
const u3: User = { name: 'Tom', age: null } // ❌👉 ? = 可能不存在,而不是 null
3️⃣ 函数参数中的 undefined
ts
function foo(x?: number) {}等价于:
ts
function foo(x: number | undefined) {}ts
foo()
foo(undefined)
foo(1)四、null vs undefined 的实际使用约定(非常重要)
🔹 业界常见约定(强烈推荐)
| 场景 | 用哪个 | 原因 |
|---|---|---|
| 变量未初始化 | undefined | JS 原生语义 |
| 参数可选 | undefined | ? 语法 |
| 对象字段缺失 | undefined | JSON 习惯 |
| 主动“置空” | null | 明确表达“空” |
| 后端返回空值 | null | 数据库常见 |
示例
ts
let currentUser: User | null = null // 当前无用户比
ts
let currentUser: User | undefined语义更清晰
五、常见坑(前端必踩)
❌ 坑 1:直接访问可能为 null 的值
ts
function printLength(s: string | null) {
console.log(s.length) // ❌
}✅ 正确方式:缩小类型(类型守卫)
ts
function printLength(s: string | null) {
if (s !== null) {
console.log(s.length) // ✅
}
}或:
ts
if (s) { } // ⚠️ 会排除 '' 0 false❌ 坑 2:DOM API
ts
const el = document.getElementById('app')
el.innerHTML = 'hi' // ❌✅ 正确写法
ts
const el = document.getElementById('app')
if (el) {
el.innerHTML = 'hi'
}或断言(你非常确定存在):
ts
const el = document.getElementById('app')!六、! 非空断言(慎用)
ts
el!.innerHTML = 'hi'含义:
“我保证它不是 null / undefined”
⚠️ 运行时不会帮你检查
七、可选链 & 空值合并(TS + ES2020 神器)
1️⃣ 可选链 ?.
ts
user?.profile?.name2️⃣ 空值合并 ??
ts
const name = user.name ?? '匿名'对比:
ts
|| // 会把 '' 0 false 当成假
?? // 只关心 null / undefined八、总结一句话(记住就行)
TS 不允许你“假装不存在 null / undefined”
你必须:
- 用联合类型声明
- 用判断缩小
- 用
?./?? - 谨慎用
!