我正在使用TypeScript〜2.7.0更新到Angular 6。在Angular 5.2.12中,我编写了这样的服务方法:
isPartDraft = (part: number): Observable<boolean> =>
this._http.get(`${this.rest}/isDraft/${part}`)
.catch(MyPartService.handleError);
用返回类型注释函数定义,但不在函数主体中声明其类型。
在某些情况下, 似乎不再可行,因为tsc
引发了
TS2322:
Type 'Observable<Object>' is not assignable to type 'Observable<boolean>'.
Type 'Object' is not assignable to type 'boolean'.
并且我被迫在current Angular documentation中推荐的函数体内声明返回类型:
isPartDraft = (part: number) =>
this._http.get<boolean>(`${this.rest}/isDraft/${part}`)
.pipe(catchError(MyService.handleError));
到目前为止,一切都很好(自从angular2-rc6以来,我们从未更改过注释,所以这可能潜伏了一段时间)。
但是在这些情况下,我没有收到任何TS错误:
getPasswordPolicy(): Observable<PasswordPolicy> {
return this._http.get(`${this.rest}/securityPolicy/`)
.pipe(
map((securityPolicy: any) => securityPolicy.passwordPolicy),
catchError(error => observableThrowError(error))
);
}
在另一项服务中:
getPartsAtDate = (id: number, date: string, time: string): Observable<number[]> =>
this._http.get(`${this.rest}/partsOnDate/${id}/${date}/${time}`)
.pipe(catchError(MyService.handleError));
getAllNewOrders = (id: number): Observable<Orders[]> =>
this._http.get(`${this.rest}/${id}`)
.pipe(catchError(MyService.handleError));
那么pipe()
,catchError()
和map()
运算符如何相互作用以产生这种情况?为什么在第一种情况下不能注释函数定义,而在后三种情况下可以注释注释?
(当然,我可以自动修复tsc引发错误的位置,但是我宁愿了解发生了什么,特别是当相同的上下文似乎会产生不同的结果时。)
根据请求,这里是错误处理程序(每个服务的实现是相同的):
private static handleError(error: any) {
console.log('error ' + error);
return observableThrowError(error.status || 'Server error');
}
答案 0 :(得分:1)
方法get
已重载,并且并非所有版本都使用泛型。根据第一个示例中的调用方式get
,选择的签名就是返回Observable<Object>
的签名。如果您想要另一种可观察的方法,则必须使用泛型(例如get<boolean>
)。
其他示例为何起作用?
map((securityPolicy: any) => securityPolicy.passwordPolicy),
在这里,您将类型从Observable<Object>
显式更改为Observable< PasswordPolicy>
。如果您有map((securityPolicy: SecurityPolicy
,它将无法正常工作。
catchError
不会像您自己的情况那样更改map
的可观察对象的类型。所以仍然是Observable<Object>
。