Javascript 如何对多层对象强制执行空检查?

Javascript 如何对多层对象强制执行空检查?,javascript,typescript,redux-saga,Javascript,Typescript,Redux Saga,我使用redux sagas通过一个公共接口从多个端点异步获取数据: export interface ResponseInfo { data?: any; status: number; headers?: any; subCode?: string; } 我希望对数据对象(必须是any类型)强制执行null检查,以便在其他开发人员尝试编写时 if(response.data.pizza.toppings){} 它将无法编译,除非他或她添加空检查 if(res

我使用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){

}

我们使用的是typescript,但是
--stricnullchecks
在没有空检查的情况下不会标记上面的行。这就是tslint的目的吗?有没有办法让typescript自己执行此检查?

我们可以使用带有索引签名的接口定义这样的对象:

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;

}