打字稿-无法将类型'void'分配给'ObservableInput <{}>'类型

迁移到TS 2.2.2后,此错误开始弹出,因此我认为这是问题所在。代码并未停止工作,但是现在我收到了该错误,并尝试了一些操作,例如返回可观察到的空值 ,捕获重新抛出的异常并返回对象,似乎没有任何效果。 为什么现在会发生这种情况? 它不应该理解我要重新抛出异常并且不期望返回吗? 我在读错误吗?

这是完整的错误描述:

enter image description here

这是完整的代码:

return request
    .map((res: Response) => res.json())
    .catch((error: any) => {
        // todo: log?

        if (error.status == 500) {
            this.alertService.showError(error.statusText);
        } else if (error.status == 588) {
            this.alertService.showAlert(error.statusText);
        }

        Observable.throw(error.statusText);
    });

我尝试返回Observable,但是我的包装方法期望返回类型T,这是我的反序列化请求(map(...))的返回值。 如果我确实返回throw,这是我得到的错误:

[ts]类型“可观察”不能分配给类型“ T”

我正在使用:

  • 角4
  • 打字稿2.2.2
eestein asked 2020-08-12T08:13:21Z
3个解决方案
59 votes

您必须返回Observable

 return request
    .map((res: Response) => res.json())
    .catch((error: any) => {
        // todo: log?

        if (error.status == 500) {
            this.alertService.showError(error.statusText);
        } else if (error.status == 588) {
            this.alertService.showAlert(error.statusText);
        }

        return Observable.throw(error.statusText);
    });
Bougarfaoui El houcine answered 2020-08-12T08:13:27Z
7 votes

有时当您调用catch而不使用如下箭头功能时

getUserList() {
    return this.http.get(this.constURL + '/api/url/here', this.headerOptions)
    .catch(this.handleError);
}

handleError(error: Response) {
    if (error.status == 500) {      
      this.router.navigate(['/login']);
    } else {
      return Observable.throw(error);
    }
}

然后给出错误

错误TypeError:无法读取未定义的属性'navigate'不能得到这个

因为在handleError函数中无法访问此对象。如果您对this.router进行控制台,则将无法定义。所以这个对象不能正常工作并且不能得到路由器所有可用的方法

所以你必须像下面这样使用箭头功能

getUserList() {
    return this.http.get(this.constURL + '/api/url/here', this.headerOptions)
    .catch(error => { 
      return this.handleError(error);
    });
}

handleError(error: Response) {
    if (error.status == 500) {      
      this.router.navigate(['/login']);
    } else {
      return Observable.throw(error);
    }
}

另外,如果您没有提到handlerError函数的return,它将再次引发错误,例如

类型'(错误:任何)=>无效'的参数不能分配给类型的参数

因此,有必要为handlerError函数键入return。

检查这里的详细信息。他为所有可能的错误和解决方案都很好地解释了代码。

Prashant M Bhavsar answered 2020-08-12T08:14:23Z
5 votes

这是RXJS 6对angular 6的解答。在您的请求函数中,它看起来与此类似。 请注意,catch已替换为return,而catchError现在是=>。同样在RXJS 6中,我们使用管道将我们希望执行的功能序列连接在一起,而不是之前的点链。

//In your service

getData(url: string): Observable<any> {
    let options = this.getHTTPOptions();
    return this.http.get<any>(url, options).pipe(
          catchError( (err: any, caught: Observable<any>) => { return 
        throwError(this.generalErrorHandler(err, caught)) } ) );
}

然后,您可以有一个错误处理程序。 关键是要在上述两个catchError函数中都指定关键字return,然后在处理程序中返回错误。箭头(3007859207275285283458)允许您将调用函数的上下文传递到错误处理程序中,这意味着您可以做一些很酷的事情,例如this.router.navigate(['someroute']);(如果您在服务中导入了路由器)

//In your service

  generalErrorHandler(error: any, caught: Observable<any>): Observable<any> {
    console.log('error caught: ', error);
    if( error.error.status == "INVALID_TOKEN" || error.error.status == "MAX_TOKEN_ISSUE_REACHED"){
      console.log('token has expired');
      this.logout();
      return error;
    }
    return error;
  }

一些关键的导入才能使它起作用:

//Imports for the service

import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
import { Http, Response } from '@angular/http';
import { catchError, map } from 'rxjs/operators';
import { Observable, throwError, of} from 'rxjs';

最后,订阅请求以获取数据:

//In your component, don't forget to import your service

let response$ = this.someService.getData('url here');
response$.subscribe( 
    data => { console.log('do stuff to data here', data); },
    err => { console.log("couldn't get data, maybe show error to user"); },
    () => { console.log('function that is called upon finish'); }
);
Josh Dando answered 2020-08-12T08:14:58Z
translate from https://stackoverflow.com:/questions/43115390/type-void-is-not-assignable-to-type-observableinput