idx:存在性函數
·2 分鐘閱讀
在 Facebook,我們經常需要存取使用 GraphQL 擷取的資料結構中,深度巢狀的值。在存取這些深度巢狀值的過程中,一個或多個中間欄位通常是可為 null 的。這些中間欄位可能因為各種原因而為 null,從隱私權檢查失敗,到 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 或未定義屬性而導致的錯誤。如果捕捉到此類錯誤,它將傳回 null 或未定義。(您可以查看如何在 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 型別宣告,允許在第二個引數中的遍歷進行適當的型別檢查,同時允許在可為 null 的屬性上進行巢狀存取。
該函數、Babel 外掛程式和 Flow 宣告現在可在 GitHub 上取得。它們透過安裝 idx 和 babel-plugin-idx npm 套件,並將 “idx” 新增到您的 .babelrc
檔案中的外掛程式清單來使用。