我想知道是否有人能向我解释这个错误,因为我对angular、typescript和rxjs相对陌生。
我尝试做的是将调用getHeroes()
时得到的服务器响应映射为一种格式,使我的组件可以轻松地使用它
这是我正在使用的getHeroes()
方法:
getHeroes(): Observable<Hero[]> {
const heroes = this.http.get<any>(this.heroesUrl)
.pipe(
map((res: EmbeddedResponse) => res._embedded.heroes),
tap(data => this.log('HeroService: fetched Heroes'),
catchError(this.handleError<Hero[]>('getHeroes', []))
))
return heroes
}
注意this.http.get<any>()
中的任意类型参数
我想更具体地介绍getHeroes()
:中的类型参数
getHeroes(): Observable<Hero[]> {
const heroes = this.http.get<Hero[]>(this.heroesUrl)
.pipe(
map((res: EmbeddedResponse) => res._embedded.heroes),
tap(data => this.log('HeroService: fetched Heroes'),
catchError(this.handleError<Hero[]>('getHeroes', []))
))
return heroes
}
请注意this.http.get<Hero[]>()
中的Hero[]类型参数
但是将getHeroes()
中的类型参数从any->英雄[]解决此错误:
error TS2345: Argument of type 'OperatorFunction<EmbeddedResponse, Hero[]>' is not assignable to parameter of type 'OperatorFunction<Hero[], Hero[]>'.
Property '_embedded' is missing in type 'Hero[]' but required in type 'EmbeddedResponse'.
EmbeddedResponse界面如下所示:
interface EmbeddedResponse {
_embedded: {
heroes: Hero[]
}
}
来自服务器的响应如下:
{
"_embedded" : {
"heroes" : [ {
"id" : 1,
"name" : "Dicke Berta",
"_links" : {
"self" : {
"href" : "http://localhost:8080/heroes/1"
},
"hero" : {
"href" : "http://localhost:8080/heroes/1"
}
}
}, {
"id" : 5,
"name" : "Cobra-Car",
"_links" : {
"self" : {
"href" : "http://localhost:8080/heroes/5"
},
"hero" : {
"href" : "http://localhost:8080/heroes/5"
}
}
} ]
},
"_links" : {
"self" : {
"href" : "http://localhost:8080/heroes"
},
"profile" : {
"href" : "http://localhost:8080/profile/heroes"
},
"search" : {
"href" : "http://localhost:8080/heroes/search"
}
}
}
您在get中定义的返回类型只分配给get函数本身,而不是整个链。您将get定义为返回类型Hero[],但在map中,您希望它是EmbeddedResponse类型。相反,定义返回EmbeddedResponse:
this.http.get<EmbeddedResponse>(this.heroesUrl)
那么你甚至不需要定义";res";在地图中,因为它已经定义好了(尽管为了可读性,您也可以保留它):
map((res) => res._embedded.heroes)
链的返回类型由最后一个元素return something定义,在用例映射中。res_embedded.heroes是Hero[]类型,因此你的const英雄将是Observable<英雄[]>。
最后,在tap-and-catchError中,您可能将括号设置错误。catchError不应该是tap的一部分,而应该被链接在它之后:
tap(data => this.log('HeroService: fetched Heroes')),
catchError(this.handleError('getHeroes', []))
);
您的catchError
操作员应该在管道内,而不是在tap
内
pipe(
map((res: EmbeddedResponse) => res._embedded.heroes),
tap(data => this.log('HeroService: fetched Heroes')),
catchError(this.handleError<Hero[]>('getHeroes', []))
))
演示