【问题标题】:Property 'data' does not exist on type 'HttpEvent<Customer>'类型“HttpEvent<Customer>”上不存在属性“数据”
【发布时间】:2018-01-23 17:07:17
【问题描述】:

我有这样的设置

  • api.service(包装httpClient模块)
  • 客户服务

api 服务获取如下:

get<T>(url: string, options?) {
return this.httpClient.get<T>(this.apiUrl + url, this.getOptions(options));}

在我的 customer.service 中,我有:

    private fetchCustomer(access_token: String): Observable<Customer> {
      const options = { headers: new HttpHeaders({ Authorization: 'Bearer ' + access_token }) };
      return this.http
        .get<Customer>('customers/me', options)
        .map(res => {
          const customer = res.data;
          customer.access_token = access_token;
          return customer;
        })
        .catch(this.handleError.bind(this));
    }

它给了我这个错误:

[ts]
Property 'data' does not exist on type 'HttpEvent<Customer>'.
Property 'data' does not exist on type 'HttpSentEvent'.

【问题讨论】:

  • 在您的 fetchCustomer 方法中 this.http 是否引用您的 api 服务?或 http 客户端
  • 它使用我的 api 服务

标签: angular http get


【解决方案1】:

解决办法是用新的方式获取json数据....

const customer = res['data'];

【讨论】:

  • 应该等同于 const customer = res.data;也许该格式绕过了打字稿编译器错误
  • hmm.. 可能是...但是如果文档说 res['data'] 那么我认为这是有原因的 ;)
【解决方案2】:

Angular 4.3 中的新 HttpClient 目前有 3 个get&lt;T&gt; 的原型

他们是

get<T>(url: string, options: {
    headers?: HttpHeaders;
    observe: 'events';
    params?: HttpParams;
    reportProgress?: boolean;
    responseType?: 'json';
    withCredentials?: boolean;
}): Observable<HttpEvent<T>>;

get<T>(url: string, options: {
    headers?: HttpHeaders;
    observe: 'response';
    params?: HttpParams;
    reportProgress?: boolean;
    responseType?: 'json';
    withCredentials?: boolean;
}): Observable<HttpResponse<T>>;

get<T>(url: string, options?: {
    headers?: HttpHeaders;
    observe?: 'body';
    params?: HttpParams;
    reportProgress?: boolean;
    responseType?: 'json';
    withCredentials?: boolean;
}): Observable<T>;

client.d.ts 顶部的评论说明了这一点。

 * Each request method has multiple signatures, and the return type varies according to which
 * signature is called (mainly the values of `observe` and `responseType`).

真正重要的部分是观察参数

get&lt;T&gt;(url, {observe: 'events'}) 返回HttpEvent&lt;T&gt;

get&lt;T&gt;(url, {observe: 'response'}) 返回HttpResponse&lt;T&gt;

get&lt;T&gt;(url, {observe: 'body'}) 返回T


注意:如果将选项部分子类化为方法,则必须返回 Object 类型,否则编译器将自动选择第一个恰好返回 HttpEvent&lt;T&gt; 的方法

所以

getOptions(): any {
    return { observe: 'body' }
};

getOptions(): any {
    return { observe: 'response' }
};

会编译到错误接口并返回HttpEvent&lt;T&gt;,但是

getOptions(): object {
    return { observe: 'body'}
};

getOptions(): object {
    return { observe: 'response'}
};

将分别返回THttpResponse&lt;T&gt;

【讨论】:

  • 除非你指定Object的类型,否则为什么它会自动选择第一个方法签名?
  • 这是一个很好的答案,似乎应该始终将选项传递给 http 方法,以确保正确解析 responseType 并使用正确的类型。
【解决方案3】:

查看 Angular 源代码 (v4.3.3),当您包装 http.get 而不指定 options 的类型时,打字稿编译器正在使用此类型定义

/**
 * 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;
    observe: 'events';
    params?: HttpParams;
    reportProgress?: boolean;
    responseType?: 'json';
    withCredentials?: boolean;
}): Observable<HttpEvent<T>>;

要让 typescript 编译器使用正确的类型定义,您可以指定选项是 Object 类型。在您的情况下,getOptions 方法应指定它返回类型 Object。

get<T>(url: string, options?) {
    return this.httpClient.get<T>(
        this.apiUrl + url, 
        this.getOptions(options) // this.getOptions needs to specify it is returning the type Object
    );
}

getOptions(options): Object {...}

现在打字稿编译器会找到正确的类型定义

/**
 * 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;
    observe?: 'body';
    params?: HttpParams;
    reportProgress?: boolean;
    responseType?: 'json';
    withCredentials?: boolean;
}): Observable<T>;

现在终于可以访问数据了

const customer = res.data;

【讨论】:

    猜你喜欢
    • 2018-11-16
    • 1970-01-01
    • 2018-10-25
    • 2018-11-18
    • 2018-10-15
    • 2023-03-10
    • 1970-01-01
    • 2021-01-09
    • 2018-11-17
    相关资源
    最近更新 更多