类型“HttpEvent<Customer>”上不存在属性“数据”
Posted
技术标签:
【中文标题】类型“HttpEvent<Customer>”上不存在属性“数据”【英文标题】:Property 'data' does not exist on type '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 服务 【参考方案1】:解决办法是用新的方式获取json数据....
const customer = res['data'];
【讨论】:
应该等同于 const customer = res.data;也许该格式绕过了打字稿编译器错误 hmm.. 可能是...但是如果文档说 res['data'] 那么我认为这是有原因的 ;)【参考方案2】: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>;
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<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'
;
和
getOptions(): any
return observe: 'response'
;
会编译到错误接口并返回HttpEvent<T>
,但是
getOptions(): object
return observe: 'body'
;
和
getOptions(): object
return observe: 'response'
;
将分别返回T
和HttpResponse<T>
【讨论】:
除非你指定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;
【讨论】:
以上是关于类型“HttpEvent<Customer>”上不存在属性“数据”的主要内容,如果未能解决你的问题,请参考以下文章