Angular HttpClient return 期待 observable<HttpEvent<any> 而不是 observable<any>

Angular HttpClient return expecting observable<HttpEvent<any> rather than observable<any>

我在使用 HttpClient 时遇到 return 类型的编译错误。在我的函数 GetPortfolio 中,我期望 GET 调用 return 类型 Observable<Portfolio> 的 json 对象,但它给出了错误:

类型 Observable<HttpEvent<Portfolio>> 不能分配给类型 Observable<Portfolio>。类型 HttpEvent<Portfolio> 不能分配给类型 Portfolio。类型 HttpProgressEvent 不可分配给类型 Portfolio。 属性 name 在类型 HttpProgressEvent 中缺失。

我的代码:

import { Injectable } from '@angular/core';
import { environment } from './environments/environment';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';


export interface Portfolio {
  name: string;
  id: string;
}

@Injectable()
export class PortfolioService {

    private httpOptions;

    apiUrl: string;

    constructor(private http: HttpClient) {
      this.apiUrl = environment.apiUrl + "/api/portfolios";

      this.httpOptions = {
        headers: new HttpHeaders(
          {
            'Content-Type': 'application/json',
          })   
      };
    }


    GetPortfolio(portfolioId: string): Observable<Portfolio> {
      return this.http.get<Portfolio>(this.apiUrl + '/${portfolioId}', this.httpOptions);
   }

}

来自 angular 英雄教程和文档 HttpClient 请求应该期待 Observable<any>Angular HttpClient doc

那我是不是做错了什么?或者我应该将 return 值设置为 Observable<HttpEvent<Portfolio>> 吗?

因为这是一个服务'PortfolioService'我们这里可能不需要接口,相反我们可以使用类型any,而且这里只需要GET方法。

GetPortfolio(portfolioId): Observable<any> {
  return this.http.get(this.apiUrl + '/${portfolioId}')
         .map((response:any) => {
              return response;
         });
}

这应该可以,请尝试。

奇怪,写了就别报错了

GetPortfolio(portfolioId: string): Observable<Portfolio> {
    return this.http.get<Portfolio>('....', {
        headers: new HttpHeaders(
            {
                'Content-Type': 'application/json',
            })   
    });
}

看起来,编译器期望 object 具有属性 headers、params、observe...,但由于您的 object 没有类型,编译器可以接受它

你也能做到

headers: HttpHeaders = new HttpHeaders({
        'Content-Type': 'application/json',
    })
GetPortfolio(portfolioId: string): Observable<Portfolio> {
        return this.http.get<Portfolio>('...', {
            headers: this.headers
        })
    }

强制转换您的 httpOptions

private httpOptions: {
    headers: HttpHeaders
};

typescript 编译器正在提取错误的 get 方法类型 (src)

/**
* Construct a GET request which interprets the body as JSON and returns the full event stream.
*
* @return an `Observable` of all `HttpEvent`s for the request, with a body type of `T`.
*/
get<T>(url: string, options: {
    headers?: HttpHeaders | {[header: string]: string | string[]},
    observe: 'events',
    params?: HttpParams|{[param: string]: string | string[]},
    reportProgress?: boolean,
    responseType?: 'json',
    withCredentials?: boolean,
}): Observable<HttpEvent<T>>;

当您使用 headers 指定类型时,它会提取正确的类型。 (src)

/**
* Construct a GET request which interprets the body as JSON and returns it.
*
* @return an `Observable` of the body as type `T`.
*/
get<T>(url: string, options?: {
    headers?: HttpHeaders | {[header: string]: string | string[]},
    observe?: 'body',
    params?: HttpParams|{[param: string]: string | string[]},
    reportProgress?: boolean,
    responseType?: 'json',
    withCredentials?: boolean,
}): Observable<T>;

我解决了这个投射我的 header 参数这样的问题

return this.http.get<SomeModel>(someUrl, <Object>this.options);

各种回答都提到了,简而言之:

您的选项必须是类型 object 而不是类型 any

根据Angular Great Docs

您可以通过将 httpOptions 中的 observe 设置为“response”来简单地解决这个问题

getConfigResponse(): Observable<HttpResponse<Config>> { return this.http.get<Config>( this.configUrl, { observe: 'response' }); }

这将 return HttpResponse<Config> 而不是 Config 只有当我们没有设置 observe ='response'