【问题标题】:Missing the following properties from type 'Map<string, Commune>': clear, delete, forEach, get'Map<string, Commune>' 类型缺少以下属性:clear、delete、forEach、get
【发布时间】:2021-10-01 04:17:03
【问题描述】:

Java 编写的REST 控制器返回法国城市的java.util.Map&lt;String, Commune&gt;

/**
 * Obtenir la liste des communes.
 * @param anneeCOG Année de référence du Code Officiel Géographique.
 * @return Liste des communes.
 * @throws TechniqueException si un incident survient.
 */
@Operation(description = "Retourne les communes du Code Officiel Geographique en vigueur une année particulière sous forme de Map.")
@RequestMapping(value = "/communes", method=RequestMethod.GET)
@ApiResponses(value = {
     @ApiResponse(responseCode = "200", description = "Communes présentes sur le territoire cette année là, sous la forme d'une Map<String, Commune>."),
     @ApiResponse(responseCode = "500", description = "Un incident est survenu durant l'extraction des communes.")
   }
)   
public Map<String, Commune> obtenirCommunes(
   @Parameter(name = "anneeCOG", description = "Année du Code Officiel Géographique.", example = "2019")
   @RequestParam(name="anneeCOG") int anneeCOG) throws TechniqueException {
   return this.cogService.obtenirCommunes(this.session, anneeCOG);
}

通过 OpenApi (Swagger) 生成一个 openapi.json 文件来描述它,在 Angular 方面,一个命令:

npm run generate:api

为此函数生成cogController.service.ts

/**
 * Retourne les communes du Code Officiel Geographique en vigueur une année particulière sous forme de Map.
 * @param anneeCOG Année du Code Officiel Géographique.
 * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
 * @param reportProgress flag to report request and response progress.
 */
public obtenirCommunes(anneeCOG: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: '*/*'}): Observable<{ [key: string]: Commune; }>;
public obtenirCommunes(anneeCOG: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: '*/*'}): Observable<HttpResponse<{ [key: string]: Commune; }>>;
public obtenirCommunes(anneeCOG: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: '*/*'}): Observable<HttpEvent<{ [key: string]: Commune; }>>;
public obtenirCommunes(anneeCOG: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: '*/*'}): Observable<any> {
    if (anneeCOG === null || anneeCOG === undefined) {
        throw new Error('Required parameter anneeCOG was null or undefined when calling obtenirCommunes.');
    }

    let queryParameters = new HttpParams({encoder: this.encoder});
    if (anneeCOG !== undefined && anneeCOG !== null) {
        queryParameters = this.addToHttpParams(queryParameters,
        <any>anneeCOG, 'anneeCOG');
    }

    let headers = this.defaultHeaders;

    let httpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept;
    if (httpHeaderAcceptSelected === undefined) {
        // to determine the Accept header
        const httpHeaderAccepts: string[] = [
            '*/*'
        ];
        httpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
    }
    if (httpHeaderAcceptSelected !== undefined) {
        headers = headers.set('Accept', httpHeaderAcceptSelected);
    }


    let responseType: 'text' | 'json' = 'json';
    if(httpHeaderAcceptSelected && httpHeaderAcceptSelected.startsWith('text')) {
        responseType = 'text';
    }

    return this.httpClient.get<{ [key: string]: Commune; }>(`${this.configuration.basePath}/cog/communes`,
        {
            params: queryParameters,
            responseType: <any>responseType,
            withCredentials: this.configuration.withCredentials,
            headers: headers,
            observe: observe,
            reportProgress: reportProgress
        }
    );
}

当我尝试在 subscribe 中的 communes.component.ts 组件中使用此 obtenirCommunes(...) 方法时:

import { Component, OnInit, Input } from '@angular/core';

import { CogControllerService } from './../../../openapi/api/cogController.service';
import { Commune } from 'openapi';

/**
 * Combobox en autocomplete des communes du COG.
 */
@Component({
  selector: 'communes',
  templateUrl: './communes.component.html',
  styleUrls: ['./communes.component.css']
})
export class CommunesComponent implements OnInit {
  /** Année du Code Officiel Géographique. */
  @Input()
  anneeCOG: number;

  /** Locale du tri des communes */
  @Input()
  locale: string = "fr_FR";

  /** Liste des communes ordonnées par locale */
  communes: Commune[];

  /** Liste des communes sous forme de Map, pour la vérification rapide de validité */
  verificationCommunes: Map<string,Commune>;

  /** Code commune sélectionné. */
  codeCommune: string = null;

  /** Commune sélectionnée. */
  commune: Commune = null;

  /**
   * Construire une instance du composant.
   * @param cogService Service REST d'accès au Code Officiel Géographique.
   */
  constructor(private readonly cogService: CogControllerService) { }

  /**
   * Renvoyer le code commune de la commune sélectionnée.
   */
  public getCodeCommune(): string {
    return this.codeCommune;
  }

  /**
   * Renvoyer la commune sélectionée.
   */
  public getCommune() : Commune {
    return this.commune;
  }

  /**
   * Déterminer si une commune a été sélectionnée.
   */
  public hasCommuneSelected() : boolean {
    return !this.codeCommune;
  }

  /**
   * Réaction à l'initialisation du composant : 
   * Lire les communes triées par locale, et sous forme de Map indexée par codeCommune.
   */
  ngOnInit(): void {
    // Vérification du paramètre d'appel (année)
    if (this.anneeCOG < 2019 || this.anneeCOG >= 2100) {
      let message = "L'année du code officiel géographique "+ this.anneeCOG + " n'est pas valide : choissez-là à partir de 2019.";
      console.log(message);
      return;
    }

    this.cogService.obtenirCommunes(this.anneeCOG).subscribe(data => {
      this.verificationCommunes = data;
    });

    this.cogService.obtenirCommunesTriParLocale(this.anneeCOG, this.locale).subscribe(data => {
      this.communes = data;
    });
  }

我收到这条消息:

error TS2740: Type '{ [key: string]: Commune; }' is missing the following properties from type 'Map<string, Commune>': clear, delete, forEach, get, and 8 more.

75       this.verificationCommunes = data;

涉及功能:

this.cogService.obtenirCommunes(this.anneeCOG).subscribe(data => {
   this.verificationCommunes = data;
});

发生了什么,我应该如何更正我的组件communes.component.ts

【问题讨论】:

    标签: java angular typescript swagger openapi


    【解决方案1】:

    嗯,Typescript 错误很容易解释。

    obtenirCommunes() 返回的Observable 产生的数据是{ [key: string]: Commune; } 类型,但你的this.verificationCommunes 变量是Map&lt;string, Commune&gt; 类型,Typescript 告诉你,为了分配给这个变量,你需要对要分配的对象有一些强制方法。

    您没有这些方法的原因是没有进行映射来将您从后端接收到的数据(默认情况下将 JSON 转换为普通的旧 Javascript 对象)转换为 实例 Map.
    如果要赋值给Map,需要构造一个Map

    const map: Map<string, Commune> = new Map();
    map.set("Paris", commune);
    ...
    

    您可能想问自己的另一个问题是:您真的需要Map吗?

    【讨论】:

    • 那么 obtenirCommunes() 应该返回 Map&lt;string, Commune&gt; 的 Observable 而不是 { string, Commune } 单个项目(如果我理解你的话),因为 Java 方法返回一个Map&lt;String, Commune&gt; 这是一个集合。
    • @MarcLeBihan 不,这是两种不同的语言,Typescript 不可能知道你在 Java 中使用的对象类型。当你的前端查询你的 API 时,你看到的就是你的 Java Map 序列化为 JSON:{"key1": {"name": "Paris", "zipCode": 75000}, "key2": {}, ...} 然后,它将这个 JSON 转换为一个简单的 Javascript 对象,仅此而已。 Javascript Map 类型是一个更复杂的对象,如果你想使用与之关联的方法,你需要显式地构造它。
    猜你喜欢
    • 2021-07-15
    • 2019-09-11
    • 2018-03-03
    • 2019-06-21
    • 2020-09-28
    • 2021-04-20
    • 2021-07-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多