0Pricing
TypeScript Academy · 课时

组合 ?. 与 ??

将可选链与合理的默认值结合使用。

组合 ?. 与 ?? 是 CoddyKit 上的免费 TypeScript Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 TypeScript Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 TypeScript Academy 课程共包含 4 节课。

完美搭配

可选链和空值合并运算符就是为配合使用而设计的。obj?.value ?? fallback 这一模式可以安全地读取嵌套值,并在值缺失时提供默认值。这是现代 TypeScript 中最实用的惯用写法之一。

type User = { profile?: { name?: string } };
const u: User = {};
const name = u.profile?.name ?? 'Anonymous';
console.log(name);

模式的工作方式

首先,?. 会计算整个链,得到该值或 undefined。然后,?? 会检查这个结果:如果结果为空值,就使用 fallback。两个运算符,一个简洁的表达式。

type Cfg = { server?: { port?: number } };
const cfg: Cfg = { server: {} };
const port = cfg.server?.port ?? 8080;
console.log(port);

结果的类型

这条链会产生 T | undefined;?? 会移除 undefined,并将 fallback 的类型合并进联合类型。使用匹配的 fallback 时,最终类型就只是 T,不再需要处理 undefined。

type Cfg = { timeout?: number };
const cfg: Cfg = {};
const timeout: number = cfg.timeout ?? 30;
console.log(timeout + 5); // number, safe arithmetic

保留有效的假值

由于 ?? 只会在结果为空值时触发,因此通过这条链获取到的合法 0 会被保留。只有属性确实缺失时,才会应用 fallback。

type Audio = { settings?: { volume?: number } };
const a: Audio = { settings: { volume: 0 } };
console.log(a.settings?.volume ?? 50); // 0, not 50

访问深层配置

对于深层嵌套的配置,可以串联多个 ?. 步骤,最后使用一个 ??。其中任何一层缺失时,都会简洁地回退到默认值。

type Cfg = { db?: { pool?: { max?: number } } };
const cfg: Cfg = { db: {} };
const maxPool = cfg.db?.pool?.max ?? 10;
console.log(maxPool);

API 响应的默认值

API 响应经常会省略可选字段。组合使用这两个运算符可以防御性地读取这些字段,并替换为合理的默认值,让后续代码保持简单且不会崩溃。

type Res = { data?: { items?: string[] } };
const res: Res = { data: {} };
const items = res.data?.items ?? [];
console.log('Item count:', items.length);

结合方法结果

您可以对函数或方法调用的结果使用链式访问,并为结果设置默认值。如果调用返回空值,就会使用 fallback。

type Store = { find?: () => string | undefined };
const store: Store = { find: () => undefined };
const result = store.find?.() ?? 'default';
console.log(result);

避免冗长的保护代码

在有这些运算符之前,您需要编写多行的空值检查。这个组合惯用写法用一个表达式替代了整个代码块,在不牺牲安全性的同时提高了可读性。

type User = { name?: string };
const u: User = {};
// Old: let n; if (u && u.name) n = u.name; else n = 'Guest';
const n = u?.name ?? 'Guest';
console.log(n);

回退到另一个查找结果

?? 后面的 fallback 本身也可以是另一个链式查找,这样您就能在使用最终的字面量默认值之前,先尝试备用来源。

type Prefs = { theme?: string };
const userPrefs: Prefs = {};
const sitePrefs: Prefs = { theme: 'light' };
const theme = userPrefs?.theme ?? sitePrefs?.theme ?? 'dark';
console.log(theme);

结合元素访问

这种模式同样适用于数组元素访问:通过 ?.[i] 读取元素,再使用 ?? 为它设置默认值。

type Data = { tags?: string[] };
const d: Data = { tags: [] };
const first = d.tags?.[0] ?? 'none';
console.log(first);

真实场景中的设置读取器

综合运用这些知识:设置读取器可以安全地逐层访问可选配置,并保证得到一个可用的值。这是您在生产环境 TypeScript 中经常会编写的代码。

type Settings = { ui?: { lang?: string } };
function getLang(s: Settings): string {
  return s.ui?.lang ?? 'en';
}
console.log(getLang({ ui: { lang: 'tr' } }), getLang({}));

快速检查

测试您对组合使用 ?. 和 ?? 的理解。

回顾:组合使用 ?. 和 ??

您学会了惯用写法 obj?.value ?? fallback:

  • ?. 会安全地逐层访问,得到该值或 undefined。
  • ?? 仅在结果为空值时提供默认值。
  • 最终类型会去掉 undefined,通常会变成简洁的 T。
  • 像 0 这样的有效假值会被保留。

接下来学习可选调用和可选元素访问。

type Cfg = { limit?: number };
const c: Cfg = {};
const limit = c?.limit ?? 100;
console.log(limit);

常见问题解答

「组合 ?. 与 ??」课时是免费的吗?

是的 — 「组合 ?. 与 ??」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 TypeScript Academy 课程的其余内容,请升级到 CoddyKit PRO。 TypeScript Academy 课程共包含 4 节课。

「组合 ?. 与 ??」这节课中我会学到什么?

将可选链与合理的默认值结合使用。 你通过在浏览器中直接运行的动手代码来练习 TypeScript Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 TypeScript Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 TypeScript Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「组合 ?. 与 ??」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 TypeScript Academy 课中编写并运行代码吗?

能。每节 TypeScript Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 使用 ?. 进行可选链调用
  2. 使用 ?? 进行空值合并
  3. 组合 ?. 与 ??
  4. 可选调用与元素访问
← 返回 TypeScript Academy