1

问题描述

this.http.get() 在类型推断中喊错

error TS2322: Type 'Observable<ArrayBuffer>' is not assignable to type 'Observable<IInfo[]>'.
  Type 'ArrayBuffer' is missing the following properties from type 'IInfo[]': length, pop, push, concat, and 27 more.

下面是代码:

// type declaration
export interface IQueryParams {
    startTime: number;
    endTime: number;
    orderType: string;
}

export interface IInfo {
    name: string;
}

// inside the service
getInfo(queryDataParams: IQueryParams): Observable<IInfo[]> {
        return this.http.get<IInfo[]>(`xxx.com`, {
        params: queryDataParams
    });
}

分析

我发现这是参数的类型问题。在 Angular 的声明中,params 对象需要是HttpParams | {[param: string]: string | string[]} ,但我发送给它一个{[param: string]: number}

也许打字稿找不到最好的声明,所以它使用第一个

解决

我可以通过将参数 obj 解析为 HttpParams 类型 obj 或将参数设置为任何来解决问题,两者都有效

// tool function
function generateHttpParams(params: Object): HttpParams; // parse obj to HttpParams


// parse to HttpParams
getInfo(queryDataParams: IQueryParams): Observable<IInfo[]> {
        return this.http.get<IInfo[]>(`xxx.com`, {
        params: generateHttpParams(queryDataParams)
    });
}

// set as any
getInfo(queryDataParams: IQueryParams): Observable<IInfo[]> {
        return this.http.get<IInfo[]>(`xxx.com`, {
        params: queryDataParams as any
    });
}

但我认为也许在 get 类型声明中{[param: string]: string | string[]}变成更合适{[param: string]: any}

4

1 回答 1

1

我在处理请求参数时经常使用的一种模式是:

yourServiceMethod(requestParams: YourInterface): Observable<YourResponseType> {

  let params = new HttpParams();
  Object.keys(requestParams).forEach(key => params = params.append(key, requestParams[key]));

  return this.httpClient
             .get<YourResponseType>(this.baseUrl, { params })
             .pipe(
               map(response => response),
               catchError(() => of(null)),
             );  
}

当然,您可以创建一个共享函数来执行从对象到 HttpParams 的转换。归根结底,这些值必须转换为要通过查询字符串传递的字符串,因此需要来自 Angular 的接口。

于 2021-01-29T03:41:51.797 回答