【问题标题】:Angular rxjs reusable pipe logic with generic type具有泛型类型的 Angular rxjs 可重用管道逻辑
【发布时间】:2022-01-09 10:18:45
【问题描述】:

我有一个基本的服务和模型来获取一些看起来像这样的数据:

//api.model.ts
interface ApiErrorResponse {
  hasError: boolean;
  error?: {
    code: number;
    errorDomain: string;
    description: string;
    field: string;
  };
}

interface ApiGetResponse<T> extends ApiErrorResponse {
  response?: {
    items?: T[];
  };
}

 //some.service.ts
 
 import ...
 
 interface Item {
   name: string;
   value: number;
 }

 type ItemApiResponse = ApiGetResponse<Item>;

 class SomeUnNamedService {
   constructor(private http: HttpClient) {
   
   public getSomeData( userId: number): Observable<ItemApiResponse> {
     this._loadingSubject.next(true);
     this._errorSubject.next(false);

     return this.http.post<ItemApiResponse>(
     `${environment._API_}/Some/Api/EndPoint`,
     { 
       userId 
     }
   ).pipe(
    map( res => {
      if(res.response?.items?.length === 0) {
         this._emptySubject.next(true);
      }
      return res;
    }),
    catchError((err: ApiErrorResponse) => {
      this._errorSubject.next(true);
      return throwError(err);
    }),
    finalize(() => this._loadingSubject.next(false))
  );
}

上面的代码工作正常,一切都很好。但是我的计划是让这个管道(?)操作员(?)可重复使用,因为我将在多个服务中使用它。所以我在https://stackoverflow.com/a/50908353/1501643的帮助下创建了这个

function responseObserver<T>(thisArg) {
  return pipe(
    map((res: T) => {
      //  Property 'response' does not exist on type 'T'.
      console.log(res?.response);

      thisArg._emptySubject.next(true);

      return res;
    }),
    catchError((err: ApiErrorResponse) => {
      thisArg._errorSubject.next(true);
      return throwError(err);
    }),
    finalize(() => thisArg._loadingSubject.next(false))
  );
}

// I invoke it like this:
public getSomeData(
    userId: string,
  ): Observable<ItemApiResponse> {
    .....
    return this.http
      .post<ItemApiResponse>(
        `${environment._API_}/Some/Api/Endpoint`,
        {
          userId
        }
      )
      .pipe(responseObserver<ItemApiResponse>(this));
  }

但是,正如您所见,TS 编译器抱怨“响应”不退出... 我在这里想念什么?为什么编译器不能解释泛型类型? 我正在使用 TypeScript 3.8

【问题讨论】:

    标签: angular typescript rxjs


    【解决方案1】:

    您假设泛型类型将包含 response 属性,但您尚未定义任何规则让编译器做出该假设。在您的功能上添加这样的规则 - function responseObserver&lt;T extends ApiGetResponse &lt;T&gt;&gt;(thisArg) - 应该允许您从泛型类型访问响应属性而不会出现编译器错误,因为它让编译器知道您的泛型类型将具有 ApiGetResponse 对象的属性,该对象确实具有响应属性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多