首页 > 解决方案 > Typescript 建模:当 IDE 不知道结构时如何处理来自 API 的对象

问题描述

我正在从API发送对象的JSON对象中提取天气数据。现在我想对这个对象做一些事情并访问它的一个属性。但当然,IDE 不知道对象结构,它告诉我“对象”类型上不存在属性“x”。尽管如此,在实践中,代码当然可以工作。但是有什么办法可以解决这个问题吗?

标签: jsonangulartypescriptapi

解决方案


在没有看到您的代码的情况下,我认为您可以应用 3 种不同的方法:

1)一个简单的解决方案是让您使用泛型 T类型:

  public getJSON<T>(): Observable<T> {
    return this.http.get<T>(url).pipe(
      tap(data => console.log(`JSON::get (tap)\n\tdata: %o`, data)),
      catchError(err => console.log(err))
    );
  }

你可以定义一个这样的接口:

export interface GenericServerResponse {
   [x: string]: any
}

component.ts并在你的我猜中使用这个界面。

public componentData: GenericServerResponse = null;

然而,这种方法消除了在项目中使用 typescript 的乐趣。

2)您也可以使用union types,例如,服务响应可以是不同的类型,如下所示:

public getJSON(): Observable<UserModel | AdminModel | SuperUserModel> {
  return this.http.get<UserModel | AdminModel | SuperUserModel>(url).pipe(
  ...
}

或者更好,因为我们将重用它,声明类型:

export type ConfigModel = UserModel | AdminModel | SuperUserModel;

public getJSON(): Observable<ConfigModel>

这很简单,也更可靠,但您需要了解您可以收到的不同型号。

3)我认为你应该这样做,因为你必须有天气 API 的完整响应,映射整个模型 4 示例:

export interface WeatherModel {
   temp: number;
   wind: number;
   cloudCoverage: number;
   city: {
    id: number;
    name: string;
   };
   ... --> the rest of the model from the API, you don't necessarily have to put all the API's attributes, only the ones you use in your app.
}

然后你只需要使用Partial 实用程序类型

public getJSON(): Observable<Partial<WeatherModel>> {
  return this.http.get<Partial<WeatherModel>>(url).pipe(
  ...
}

Partial 使接口的每个属性都是可选的。这样 IDE 会很高兴并向您显示对象属性。

如果您需要在组件中输入数据,只需对 Partial 执行相同操作:

public componentData$: Observable<Partial<WeatherModel>>;
...
this.componentData$ = this.httpService.getJSON().subscribe(
  (resp: Partial<WeatherModel>) => console.log(resp.city.name)
);    

推荐阅读