这个问题在SO上被询问了大约1万亿次,但没有一个帖子回答我的问题。所以我再问一次。
以下是我的方法(在service
中),该方法发出了发布请求。
makePostReq<T>(reqObj: {url:string, body:any, headerData?:any}): Observable<T>{
let headers = this.createHeaders(reqObj.headerData);
return this.httpClient.post<T>(reqObj.url, reqObj.body, {headers:headers})
.catch((e: any ) => {
console.log(e);
this.utilityService.showErrorToaster(e);
});
}
该方法希望捕获HTTPError
,然后将其记录下来,然后向用户显示有关该错误的烤面包机/警报。
问题:
以上代码给出此错误:
TS2345: Argument of type '(e: any) => void' is not assignable to parameter of type '(err: any, caught: Observable<T>) => ObservableInput<{}>'. Type 'void' is not assignable to type 'ObservableInput<{}>'.
我已经知道:
我完全知道为什么会出现此错误。我知道catch应该返回类型Observable<T>
的对象,但是我没有任何返回类型T
的对象。返回Observable.of(null)
也不起作用。
我也知道,如果删除通用的<T>
,我不会收到此编译错误。
我的问题:
如何在不损害generics
的情况下使上述代码正常工作。
答案 0 :(得分:0)
我认为在makePostReq<T>(...)
中捕获错误的整个想法是令人误解的。
这是为什么。
首先,通过返回Observable<T>
,我们说我们的方法将在某个时刻(当内部的http调用响应时)发出T
类型的值。如果我们处理makePostReq<T>(...)
内的错误,则必须发出T
的伪实例(例如null
)来满足我们的编译器要求。这意味着您还必须通过过滤掉null
(类似于makePostReq<string>(...).pipe(filter(str => str !== null))
)来在调用者中处理此问题,这意味着您实际上可以两次处理错误,而您只能在调用者中处理异常像makePostReq<string>(...).pipe(catchError(error => utilityService.showErrorToaster(error)))
。
其次,通过使您的呼叫通用,我假设您打算从各种服务/针对各种类型的T
进行呼叫。通过处理makePostReq<T>(...)
内部的错误并调用this.utilityService.showErrorToaster(e);
,您就可以将错误处理限制为仅弹出Toast通知,而没有其他任何操作。如果某个时候您需要重定向到错误页面,而又想做一些不同的事情怎么办?与调用者仅进行错误处理相比,使用此设置将更加困难。
所以我建议您将其保留为
makePostReq<T>(reqObj: {url:string, body:any, headerData?:any}): Observable<T>{
let headers = this.createHeaders(reqObj.headerData);
return this.httpClient.post<T>(reqObj.url, reqObj.body, {headers:headers});
}