javascript - 如何对多层深的对象强制执行空检查?
问题描述
我正在使用 redux sagas 通过一个通用接口从多个端点异步获取数据:
export interface ResponseInfo {
data?: any;
status: number;
headers?: any;
subCode?: string;
}
我想对数据对象(必须是 any 类型)强制执行 null 检查,以便当另一个开发人员尝试编写
if(response.data.pizza.toppings){}
除非他或她添加空检查,否则它将无法编译,
if(response.data && response.data.pizza && response.data.pizza.toppings){
}
我们正在使用打字稿,但--strictNullChecks
不会在没有空检查的情况下标记上述行。这是 tslint 中no-unsafe-any的用途吗?有没有办法让打字稿自己做这个检查?
解决方案
我们可以使用带有索引签名的接口来定义这样的对象:
export interface ResponseInfo {
data?: RecursiveObject;
status: number;
headers?: any;
subCode?: string;
}
interface RecursiveObject {
[s: string]: RecursiveObject | undefined
}
// Usage
declare let response : ResponseInfo
if(response.data.pizza.toppings){ // Object is possibly 'undefined'
}
if(response.data.pizza){ // Object is possibly 'undefined'
}
一个问题是response.data.pizza.toppings
不是RecursiveObject
很有用。为了解决这个问题(并且也更加安全),我们可以使用自定义类型保护来将最终结果的类型缩小到有用的范围内。(请注意,常规类型保护不起作用,因为RecursiveObject
与字符串无关,而简单的保护例如typeof response.data.pizza.toppings === 'string'
实际上会缩小到never
)
function isString(o: RecursiveObject|string ): o is string {
return typeof o === "string"
}
declare let response : ResponseInfo
if(response.data && response.data.pizza && response.data.pizza.toppings
&& isString(response.data.pizza.toppings) ){
let s : string = response.data.pizza.toppings;
}
有点冗长,但可能有用。
推荐阅读
- vuejs2 - 如何将所有道具动态传递给子组件
- jenkins - 从詹金斯到同一主机的SSH
- vba - Excel VBA将范围放入数组
- azure-devops - 是否可以在 VSTS 中单独重新运行验证阶段(无需重新构建)?
- javascript - Puppeteer 没有更改我的 IP
- vba - VBA:防止 Excel 在打开时更新链接
- google-cloud-sdk - Amazon Linux AMI 2018.03 - 谷歌云 sdk 安装
- javascript - 当有人直接打开页面时如何进行基于令牌的身份验证
- ssas-tabular - 表格对象模型的 Tableau 性能问题
- ruby-on-rails - Sidekiq 宝石与 Ruby 1.9.3