'HttpEvent <Customer>'类型中不存在属性'data'

Mac*_*ito 5 get http angular

我有这样的设置

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

api服务看起来像这样:

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

在我的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));
    }
Run Code Online (Sandbox Code Playgroud)

它给了我这个错误:

[ts]
Property 'data' does not exist on type 'HttpEvent<Customer>'.
Property 'data' does not exist on type 'HttpSentEvent'.
Run Code Online (Sandbox Code Playgroud)

LLa*_*Lai 9

查看角度源代码(v4.3.3),当你在不指定typescript options编译器类型的情况下包装http.get时使用此类型定义

/**
 * 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>>;
Run Code Online (Sandbox Code Playgroud)

要使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 {...}
Run Code Online (Sandbox Code Playgroud)

现在,typescript编译器将找到正确的类型定义

/**
 * 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>;
Run Code Online (Sandbox Code Playgroud)

最后你现在可以访问数据了

const customer = res.data;
Run Code Online (Sandbox Code Playgroud)


Mac*_*ito 7

解决方案是使用获取json数据的新方法。

const customer = res['data'];
Run Code Online (Sandbox Code Playgroud)

  • 应该与const customer = res.data相同;也许该格式绕过了打字稿编译器错误 (2认同)

mut*_*nUp 6

Angular 4.3中的新HttpClient目前有3种原型 get<T>

他们是

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>;
Run Code Online (Sandbox Code Playgroud)

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`).
Run Code Online (Sandbox Code Playgroud)

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

get<T>(url, {observe: 'events'}) 回报 HttpEvent<T>

get<T>(url, {observe: 'response'}) 回报 HttpResponse<T>

get<T>(url, {observe: 'body'}) 回报 T


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

所以

getOptions(): any {
    return { observe: 'body' }
};
Run Code Online (Sandbox Code Playgroud)

getOptions(): any {
    return { observe: 'response' }
};
Run Code Online (Sandbox Code Playgroud)

将编译到错误的接口并返回HttpEvent<T>,但是

getOptions(): object {
    return { observe: 'body'}
};
Run Code Online (Sandbox Code Playgroud)

getOptions(): object {
    return { observe: 'response'}
};
Run Code Online (Sandbox Code Playgroud)

将返回THttpResponse<T>分别