26

Angular 文档说:

响应正文不会返回您可能需要的所有数据。有时服务器会返回特殊的标头或状态代码来指示某些条件,并且可能需要检查这些条件。为此,您可以告诉 HttpClient 您想要完整的响应,而不仅仅是带有观察选项的正文:

http
  .get<MyJsonData>('/data.json', {observe: 'response'})
  .subscribe(resp => {
    // Here, resp is of type HttpResponse<MyJsonData>.
    // You can inspect its headers:
    console.log(resp.headers.get('X-Custom-Header'));
    // And access the body directly, which is typed as MyJsonData as requested.
    console.log(resp.body.someField);
  });

但是当我尝试这样做时,我得到一个编译时错误(虽然没有运行时错误,但按预期工作):

错误 TS2345:类型参数 '{ headers: HttpHeaders; 观察:字符串;}' 不能分配给类型为 '{ headers?: HttpHeaders | { [标题:字符串]:字符串 | 细绳[]; }; 观察?:“身体”;参数?:Ht...'。属性“观察”的类型不兼容。类型 'string' 不能分配给类型 '"body"'。

为什么?我用"@angular/http": "^5.1.0"

这是我的代码版本:

  login(credentials: Credentials): Observable<any> {
    const options = {
      headers: new HttpHeaders({'Content-Type': 'application/json'}),
      observe: 'response'
    };
    return this.httpClient.post<any>(`${environment.USER_SERVICE_BASE_URL}`,
      {'username': credentials.username, 'password': credentials.password}, options)
      .map((res) => ...
4

4 回答 4

50

您必须内联选项。请参阅github 票 #18586alxhub ,于 2017 年 8 月 9 日进入。

Typescript 需要能够静态推断观察和响应类型值,以便为 get() 选择正确的返回类型。如果你传入一个类型不正确的选项对象,它就不能推断出正确的返回类型。

login(credentials: Credentials): Observable<any> {
    return this.httpClient.post<any>(`${environment.USER_SERVICE_BASE_URL}`,
      {'username': credentials.username, 'password': credentials.password}, {
      headers: new HttpHeaders({'Content-Type': 'application/json'}),
      observe: 'response'
    })
      .map((res) => ...
于 2017-12-11T21:13:34.453 回答
35

打字稿抱怨这个问题

类型“字符串”不可分配给类型“正文”

要解决此问题,请手动将字符串转换为正文。例子:

    const httpOptions = {
      headers: new HttpHeaders({
        'Content-Type': 'application/json'
      }),
      observe: 'response' as 'body'
    };
    return this.http.post<any>(url, data, httpOptions);
于 2019-01-16T13:25:23.273 回答
10

我解决这个问题的方法是为请求选项创建一个接口,而不内联选项(这可能导致代码不那么干净)。代码如下所示:

export interface IRequestOptions {
    body?: any;
    headers?: HttpHeaders | { [header: string]: string | Array<string> };
    observe?: any;
    params?: HttpParams | { [param: string]: string | Array<string> };
    reportProgress?: boolean;
    responseType?: "arraybuffer" | "blob" | "json" | "text";
    withCredentials?: boolean;
}

然后这样使用:

const options: IRequestOptions = {
    headers: new HttpHeaders({"Content-Type": "application/json"}),
    observe: "response"
};
return this.httpClient.post(`${environment.USER_SERVICE_BASE_URL}`,
    {"username": credentials.username, "password": credentials.password}, options)
    .pipe(
        map((res: HttpResponse<any>) => ...
    );

更改要使用的原始帖子lettablepipeable(无论当前名称是什么)运营商

于 2018-02-23T15:55:09.187 回答
0
import { HttpHeaders, HttpParams } from '@angular/common/http';
export interface IRequestOptions {
    headers?: HttpHeaders | { [header: string]: string | string[]; };
    observe: "response"; 
    params?: HttpParams | { [param: string]: string | string[]; };
    reportProgress?: boolean; 
    responseType?: "json";
    withCredentials?: boolean; 
}
于 2020-04-07T06:50:27.280 回答