idx:存在性函数
·2 分钟阅读
在 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,了解这可能如何实现。)
实际上,尝试捕获每个嵌套属性访问速度很慢,并且区分特定类型的 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 上可用。它们通过安装 idx 和 babel-plugin-idx npm 包,并将 “idx” 添加到你的 .babelrc
文件中的插件列表来使用。