跳到主要内容

idx:存在性函数

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

在 Facebook,我们经常需要访问使用 GraphQL 获取的数据结构中深层嵌套的值。在访问这些深层嵌套值的过程中,一个或多个中间字段通常是可为空的。这些中间字段可能因为多种原因为空,从隐私检查失败到 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 中看到这可能如何实现。)

实际上,尝试捕获每个嵌套属性访问都很慢,并且区分特定类型的 TypeErrors 很脆弱。为了解决这些缺点,我们创建了一个 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 文件中的插件列表来使用。