跳到主要内容

idx:存在函数

·2 分钟阅读
Timothy Yung
Facebook 工程经理

在 Facebook,我们经常需要访问通过 GraphQL 获取的数据结构中深度嵌套的值。在访问这些深度嵌套值的过程中,一个或多个中间字段可能为空 (nullable),这种情况很常见。这些中间字段可能为空的原因有很多,从隐私检查失败到仅仅因为 null 恰好是表示非致命错误最灵活的方式。

不幸的是,目前访问这些深度嵌套的值既繁琐又冗长。

props.user &&
props.user.friends &&
props.user.friends[0] &&
props.user.friends[0].friends;

有一项 ECMAScript 提案旨在引入存在运算符,这将使这项工作便利得多。但在该提案最终确定之前,我们需要一个既能改善我们的开发体验,又能保持现有语言语义并鼓励使用 Flow 进行类型安全的解决方案。

我们提出了一个存在函数,称之为 idx

idx(props, _ => _.user.friends[0].friends);

这段代码片段中的调用行为类似于上面代码片段中的布尔表达式,但重复明显减少。idx 函数恰好接收两个参数

  • 任何值,通常是你想访问其嵌套值的对象或数组。
  • 一个函数,接收第一个参数并在其上访问嵌套值。

理论上,idx 函数会捕获因访问 null 或 undefined 上的属性而产生的错误。如果捕获到此类错误,它将返回 null 或 undefined。(你可以在 idx.js 中看到这可能如何实现。)

实际上,对每一次嵌套属性访问都进行 try-catch 是很慢的,并且区分特定类型的 TypeError 也很脆弱。为了解决这些缺点,我们创建了一个 Babel 插件,将上面的 idx 调用转换为以下表达式

props.user == null
? props.user
: props.user.friends == null
? props.user.friends
: props.user.friends[0] == null
? props.user.friends[0]
: props.user.friends[0].friends;

最后,我们为 idx 添加了一个自定义 Flow 类型声明,它允许对第二个参数中的遍历进行正确的类型检查,同时允许访问可空属性上的嵌套值。

该函数、Babel 插件和 Flow 声明现已在 GitHub 上发布。使用方法是安装 idxbabel-plugin-idx npm 包,并将“idx”添加到你的 .babelrc 文件中的插件列表中。