假设我有一些返回可观察值的操作。
this.loginService
.post<IResponse>(url, { username, password })
.subscribe(
next => { /* I know the type of next */ },
error => { /* Can I specify type of err, or is it always any? */ }
);
我可以设置next
的类型-在这种情况下为IResponse
。
error
怎么样-我能以某种方式指定它的类型吗?还是总是any
,我总是需要在处理程序中进行类型转换?
答案 0 :(得分:3)
您可以使用括号来实现:
this.loginService
.post<IResponse>(url, { username, password })
.subscribe(
(next: TypeOfYourResponse) => {...},
(error: TypeOfYourErrorResponse) => {...}
);
有关箭头功能的进一步阅读:
https://www.tutorialsteacher.com/typescript/arrow-function
https://basarat.gitbooks.io/typescript/docs/arrow-functions.html
答案 1 :(得分:2)
根据我的经验,从HTTP操作中产生可观察值的服务永远不会发出未捕获的HTTP错误。它在该服务的使用者中创建了许多样板代码,并迫使使用者处理HTTP特定问题。
我还认为服务应该不捕获所有类型的错误,而只能捕获已知和预期的错误。要求应用程序本身使用错误拦截器处理极端情况。
export interface ILoginResponse {
//...
}
export interface IServiceResponse<TType> {
success: boolean;
payload?: TType;
}
@Injectable()
export class LoginService {
public login(options: any): Observable<IServiceResponse<ILoginResponse>> {
return this.httpClient.post<ILoginResponse>('login', options).pipe(
map(payload => ({success: true, payload})),
catchError(err => {
if(err instanceof HttpErrorResponse) {
// handle http errors here, maybe retry, update headers, etc..
return of({success: false});
}
// this error is unexpected, we don't know what to do
// let the app interceptor handle it, but upstream observables
// won't know what to do either. Our app has crashed...
// You can return success false, but why handle this error?
return throwError(err);
});
}
}
为什么要执行上述操作?
每当您使用发出未捕获错误的 route 解析器时,它都会失败路由转换。路由器将基本上崩溃。用户基本上只会看到一个空白页,因为解析器没有错误处理的回退。
以上内容仅捕获HTTP错误,因为这是我们认为应该抛出的唯一错误。另一种错误应视为错误。
如果组件调用此服务,则程序员在信任发射的值之前,应检查success
的{{1}}标志。如果业务逻辑不在乎它是否失败,或者组件可以直观地向用户显示它无法执行HTTP请求,则可以对此进行过滤。无论哪种方式,HTTP错误响应都不会传递到应用程序错误拦截器。
这只是一种方法。人们对HTTP的处理完全不同。另一个答案可以正确回答您的问题。
答案 2 :(得分:2)
使用catchError运算符的另一种方法:
this.loginService
.post<IResponse>(url, { username, password })
.catchError<TypeOfYourErrorResponse>(() => // Your catch callback)
.subscribe(
next => { /* I know the type of next */ },
);