Angular12下如何为CRUD基类动态设置Observable泛型返回类型
要实现这个需求,你应该使用Typescript泛型来定义基类的动态类型,你之前的思路行不通的原因是类型只在编译期存在,运行时的属性赋值无法作为类型声明使用。
改造后的CRUD基类代码
import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { AppHttpClient } from './app-http-client.service'; // 替换为你实际的导入路径 import { HttpParams } from '@angular/common/http'; // 泛型参数定义:T = 单条数据类型,L = 分页列表接口返回类型 @Injectable({ providedIn: 'root' }) export class CrudService<T, L> { protected endpoint: string; constructor(private http: AppHttpClient) {} list(query: {[key: string]: any}): Observable<L> { // 用Angular自带的HttpParams拼接参数,自动处理编码和多余的&符号 let params = new HttpParams(); Object.keys(query).forEach(key => { params = params.set(key, query[key]); }); return this.http.Get<L>(this.endpoint, { params }); } get(id: number | string): Observable<T> { return this.http.Get<T>(`${this.endpoint}${id}/`); } create(data: Partial<T>): Observable<T> { return this.http.Post<T>(this.endpoint, data); } update(id: number | string, data: Partial<T>): Observable<T> { return this.http.Put<T>(`${this.endpoint}${id}/`, data); } delete(id: number | string): Observable<void> { return this.http.Delete<void>(`${this.endpoint}${id}/`); } }
子服务使用示例
import { Injectable } from '@angular/core'; import { CrudService } from './crud.service'; import { CategoryItem, CategoryListResponse } from './category.interface'; @Injectable({ providedIn: 'root' }) export class CategoryService extends CrudService<CategoryItem, CategoryListResponse> { // 只需重写endpoint即可,所有方法自动继承对应的类型提示 protected override endpoint = 'category/'; }
说明
- 继承基类时给泛型传入对应的类型,基类的所有方法就会自动匹配对应的返回类型,完全符合你要求的
list返回Observable<CategoryListResponse>、get/create返回Observable<CategoryItem>的需求 - 如果你封装的
AppHttpClient是对Angular原生HttpClient的二次封装,需要确保封装的Get/Post等方法支持传入泛型参数指定返回值类型
内容的提问来源于stack exchange,提问作者Anuj TBE
相关产品推荐
相关产品推荐

