繁体   English   中英

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

[英]Angular 9 typecast issue after http response

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

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

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

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

一切正常。 现在,仅出于教学目的(我是 javascript/typescript 的新手),我想重构我的服务,以便使用单个get function 在不带参数的情况下返回学生列表,而是返回学生详细信息使用特定 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);
  }

鉴于我的 function 的签名声明它返回一个可观察的学生数组,在我的组件中,我需要一种从Student[]Student的类型转换。 我就是这样做的: component-version2

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

这不起作用,因此在 init 之后, student var 仍然未定义。 我不明白为什么,对我来说一切似乎都是正确的(尽管这种重构不是一个好主意。同样,我只是想了解背后的错误)我也尝试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)
  )
}

}

始终,尝试返回一个数组以避免冲突。 在上面的代码中,三元运算符将完成您的工作。 因为,如果您有一个 id,这意味着您正在询问特定的学生信息,否则您正在询问所有学生记录。

您的服务现在应该对您大喊大叫,因为您在对编译器撒谎……您的返回类型不是Observable<Student[]>它的Observable<Student[] | Student> Observable<Student[] | Student> ...我不同意一个 function 的负责人,无论是单身还是名单,但你可以强迫它成为单一情况下的名单......

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 的可能性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM