TypeScript Academy · 课时

可选调用与元素访问

使用 ?.() 和 ?.[] 安全地调用方法和进行索引访问。

第 4 / 4 课13 个步骤

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

超越属性访问

可选链并不局限于 obj?.prop。它还有另外两种形式:使用 ?.() 的可选调用,以及使用 ?.[index] 的可选元素访问。这两种形式都会像属性访问一样,在遇到空值时短路。

type Obj = { greet?: () => string };
const o: Obj = {};
console.log(o.greet?.()); // undefined, no crash

可选方法调用

使用 obj.method?.(),仅在方法存在时调用它。如果 method 为 null 或 undefined,则会跳过调用,表达式的结果为 undefined。

type Logger = { log?: (m: string) => void };
const silent: Logger = {};
silent.log?.('hello'); // skipped, no error
console.log('continued safely');

应将 ?. 放在哪里

?. 应紧接在调用括号之前。obj.method?.() 检查的是方法,而不是 obj。如果还要保护 obj,请写成 obj?.method?.()。

type Api = { send?: (x: number) => number };
const api: Api | null = null;
console.log(api?.send?.(5)); // undefined; guards both api and send

调用可选回调

一个非常常见的用途是调用可选的回调参数。您无需使用 if 检查,只需写成 callback?.(),即可仅在提供了回调时调用它。

function run(onDone?: () => void): void {
  console.log('working...');
  onDone?.(); // call only if passed
}
run();
run(() => console.log('finished'));

可选元素访问

对于可能为空值的数组或索引签名,请使用 arr?.[index]。如果 arr 为空值,访问会短路;否则会正常读取该元素。

const list: string[] | undefined = undefined;
console.log(list?.[0]); // undefined, no crash

使用动态键进行元素访问

对于可能为空值的对象,可选元素访问同样适用于使用方括号表示法访问动态键或计算键。

type Dict = { [key: string]: number };
const data: Dict | null = { a: 1, b: 2 };
const key = 'a';
console.log(data?.[key]); // 1

组合元素访问与调用

您可以自由组合这些形式。先访问可能为空值的数组中的元素,再可选地调用该元素上的方法——每个 ?. 都会保护自己的步骤。

type Handlers = Array<{ fire?: () => string }>;
const hs: Handlers | undefined = [{ fire: () => 'boom' }];
console.log(hs?.[0]?.fire?.());

对函数结果使用可选链

您可以继续访问函数返回的任何结果。如果函数返回空值,后续的调用或访问就会安全地短路。

function getHandler(): (() => string) | undefined {
  return undefined;
}
console.log(getHandler()?.()); // undefined

结果类型包含 undefined

与属性链一样,可选调用和元素访问会将 undefined 添加到结果类型中。请将它们与 ?? 配合使用,以提供默认值并移除 undefined。

type Obj = { compute?: () => number };
const o: Obj = {};
const value = o.compute?.() ?? 0;
console.log(value);

保护事件处理程序

在用户界面和事件代码中,可选调用可以优雅地调用可能未设置的处理程序。无需冗长的存在性检查,也不会因处理程序缺失而崩溃。

type Props = { onClick?: (id: number) => void };
function click(p: Props, id: number): void {
  p.onClick?.(id); // safe if onClick is missing
}
click({ onClick: (id) => console.log('clicked', id) }, 7);
click({}, 8);

插件分发器示例

综合运用这些知识:构建一个分发器,从可能稀疏的注册表中可选地调用指定名称的插件钩子;如果没有任何处理程序处理请求,则为结果提供默认值。

type Hooks = { [name: string]: (() => string) | undefined };
const hooks: Hooks = { save: () => 'saved' };
function fire(name: string): string {
  return hooks[name]?.() ?? 'no handler';
}
console.log(fire('save'), fire('delete'));

快速检查

检验您对可选调用和元素访问的理解。

回顾:可选调用与访问

您已了解到可选链的其他形式:

  • obj.method?.() 仅在方法存在时调用它。
  • arr?.[index] 可以安全地从可能为空值的容器中读取元素。
  • 所有形式在操作数为空值时都会短路为 undefined。
  • 与 ?? 结合使用可以为结果提供默认值。

下一门课程:readonly 与不可变性基础。

type Cfg = { init?: () => void };
const c: Cfg = {};
c.init?.();
console.log('ran safely');
免费开始

用 AI 导师学习 TypeScript — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
101
课程
352

常见问题解答

「可选调用与元素访问」课时是免费的吗?

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

「可选调用与元素访问」这节课中我会学到什么?

使用 ?.() 和 ?.[] 安全地调用方法和进行索引访问。 你通过在浏览器中直接运行的动手代码来练习 TypeScript Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 TypeScript Academy 需要有经验吗?

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

「可选调用与元素访问」课时需要多长时间?

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

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

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

此课程中的所有课时

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