Angular 服务 - 返回的对象类型是对象,而不是指定的泛型类型

Angular Service - Type of object returned is object and not that of the generic type specified

我有一个 angular5 服务,它执行 HTTP 获取和 returns 如下所示的特定类型

public getProductByIDproductId: string): Observable<Product> {
    const headers = new HttpHeaders({ "Content-Type": "application/json" });
    const url = `${environment.productservice_baseurl}/${productId}`;
    return this.http
      .get<Product>(url, { headers: headers })
      .pipe(       
        tap(data => (this._product = data)),
        catchError(this.handleError)
      );
  }

产品 class 是具有属性和方法的 class。下面是一小段摘录。

class Product{
    productID:string;
    productName:string;

    setQuantity(quantity:number){

    }
}

当我在 get 返回的 this._product 上调用 setQuantity 函数时,出现 'setQuantity is not a function' 错误。当我尝试检查 this._product 的实例时,它不是 Product 类型,而是 Object 类型。

在get方法上设置泛型类型只是为了帮助编译时类型检查吗?如何从 getProductByIDproductId 方法获取产品 class 的具体实例?

例如,您可以映射响应。

return this.http
  .get<Product>(url, { headers: headers })
  .map(response => new Product(response)) // I don't know your constructor
  .pipe(       
    tap(data => (this._product = data)),
    catchError(this.handleError)
  );

这样,您就可以确定您的对象将是您定义的 Typescript 对象。

EDIT 你可以创建一个对象 "by hand" 只有几行:

export class Product {
  // Your class ...

  public static createProductFromHttpResponse = (response: any) => {
    const ret = new Product();
    for (let key in response.key) { ret[key] = response[key]; }
    return ret;
  }
}

在您的映射中:

  .map(response => Product.createProductFromHttpResponse(response))

据我所知,要指定响应类型,您应该使用接口 类,因此您的产品应该是一个接口:

interface Product{
productID:string;
productName:string;

}

因为它只是接口和 http 响应,所以它不应该有任何方法

编辑

@trichetriche 的回答可能是这个问题的解决方案之一。

你不能做你正在做的事。

当您从 URL 获取数据时,您只会得到 JSON。您是在告诉 TypeScript dataProduct 类型,但这只是对编译器的提示,并没有使它成为现实。

data 不是通过调用 new Product 创建的,因此它不共享其方法。

如果您希望 this._product 表现得像本机 Product 实例,您可以这样做:

this._product = data;
Object.setPrototypeOf(this._product, Product.prototype);

这样您就可以将 this._product 变成一个真正的 Product 实例,包括它的方法。

如果您担心 setPrototypeOf 及其潜在的性能缺陷,另一种选择是这样做的:

this._product = new Product();
Object.assign(this._product, data);

当然,只有在 Product 具有无参数构造函数的情况下,这才是一个好主意。而且,在任何情况下,如果 data 具有 Product class 中未定义的属性,您也可以 运行 遇到性能问题。