http响应后的Angular 9类型转换问题



我有一个组件,它在初始化时从api中检索学生信息。这是我的cmcomponent-version1上的onInit代码

ngOnInit(): void {
if(!this.student) {
this.studentsService.getStudentDetail(this.id).subscribe(
(response: Student) => {
this.student = response;
},
error => console.log(error)
)
}
}

这是我的学生服务版本1中的函数

getStudentDetail(id: number): Observable<Student> {
return this.httpClient.get<Student>(`${this.studentsUrl}${id}/`, this.baseService.httpOptions);
}

一切都很好。现在,出于教学目的(我是javascript/typescript的新手(,我想重构我的服务,以便使用一个get函数,该函数在无参数调用时返回学生列表,而在使用特定id调用时返回一个学生详细信息。这是学生服务版本2

getStudents(id?: number): Observable<Student[]> {
if(id)
return this.httpClient.get<Student[]>(`${this.studentsUrl}${id}/`, this.baseService.httpOptions);
else
return this.httpClient.get<Student[]>(this.studentsUrl, this.baseService.httpOptions);
}

假设我的函数的签名声明它返回一个可观察的students数组,在我的组件中,我需要一种从Student[]Student的类型转换。我是这样做的:组件版本2

ngOnInit(): void {
if(!this.student) {
this.studentsService.getStudents(this.id).subscribe(
(response: Student[]) => {
this.student = response[0] as Student;
},
error => console.log(error)
)
}
}

这不起作用,所以在init之后,studentvar保持未定义状态。我不明白为什么,在我看来一切都是正确的(尽管这次重构不是一个好主意。再说一遍,我只想了解背后的错误(我也要试试this.student = response.pop() as Student;结果相同,不起作用。

ngOnInit(): void {
if(!this.student) {
this.studentsService.getStudents(this.id).subscribe(
(response: Student[]) => {
// Hope, this.student will have type as any, public student: any
this.student = !this.id ? response[0] as Student : response as Student[];
},
error => console.log(error)
)
}

}

总是尝试返回一个数组以避免冲突。在上述代码中,三元运算符将完成您的工作。如果你有身份证意味着你在询问特定的学生信息,否则你要求提供所有学生记录。

您的服务现在应该对您大喊大叫,因为您在对编译器撒谎。。。您的退货类型不是Observable<Student[]>而是Observable<Student[] | Student>。。。我完全不同意single和list-gets的一个函数的原理,但在single的情况下,你可以强迫它是一个列表。。。

return this.httpClient.get<Student>(`${this.studentsUrl}${id}/`, this.baseService.httpOptions).pipe(
map(student => [student])
);

如果某个东西不是数组,那么任何类型转换都不会将其转换为数组。如果你想要的话,你需要显式地使它成为一个数组。

重载方法的签名,如下所示:

class StudentService {
get(id: number) | Observable<Student>;
get(): Observable<Student[]>;
get(id: number | undefined): Observable<Student[]> | Observable<Student> {
if(id !== undefined)
return this.httpClient.get<Student[]>(`${this.studentsUrl}${id}/`, this.baseService.httpOptions);
else
return this.httpClient.get<Student>(this.studentsUrl, this.baseService.httpOptions);
}
} 

注意方法是如何被重命名以在任何一种情况下都有意义的,返回类型是如何与id参数的存在相关的,以及检查是如何被修改以适应0作为有效id的可能性的。

最新更新