跳到主要内容

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 中查看如何实现这一点。)

实际上,对每个嵌套属性访问进行 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 文件中的插件列表中来使用。