簡體   English   中英

angular 屬性“值”在“對象”類型上不存在

[英]angular Property 'value' does not exist on type 'Object'

在我的 Angular 應用程序中,我對 API 調用的響應存在問題:

 private async getActor(actor:string) {
    const response = await this.searchActor.getActorImage(actor).toPromise()
    let actPics = []    
      for (var val of (response as any[]).value) {
        actPics.push(val.thumbnailUrl)}                   
  }

我的應用程序運行良好,但是當我運行ng serve時,控制台中有此消息

錯誤:src/app/quiz-editor/actor-question/actor-question.component.ts:55:41 - 錯誤 TS2551:“任何 []”類型上不存在屬性“值”。 您指的是 'values' 嗎?

55 for (var val of (response as any[]).value) { ~~~~~

node_modules/typescript/lib/lib.es2015.iterable.d.ts:75:5 75 個值():IterableIterator; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 這里聲明了“值”。

當我console.log(response)我得到:

控制台日志(響應)

我做了一些研究,我讀到我應該聲明response ,但我應該怎么做呢?

我試過這個解決方案:

private async getActor(actor:string) {
    const response: { value:any[] } = await this.searchActor.getActorImage(actor).toPromise()
    let actPics = []      
    for (let val of response.value) {
      actPics.push(val.thumbnailUrl)}
}

但現在我有這個錯誤:

 Error: src/app/quiz-editor/actor-question/actor-question.component.ts:55:11 - error TS2696: The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead?
      Property 'value' is missing in type 'Object' but required in type '{ value: any[]; }'.

55     const response: { value:any[] } = await this.searchActor.getActorImage(actor).toPromise()
             ~~~~~~~~

  src/app/quiz-editor/actor-question/actor-question.component.ts:55:23
    55     const response: { value:any[] } = await this.searchActor.getActorImage(actor).toPromise()
                             ~~~~~
    'value' is declared here.

正如您的日志語句所示,您的response是一個包含value作為鍵的 object。 因此,您可以執行以下操作:

const response: { value: any[] } = await this.searchActor.getActorImage(actor).toPromise();
let actPics = [];
for (let val of response.value) {
  actPics.push(val.thumbnailUrl);                   
}

您必須告訴 typescript 您的陣列是什么類型。 通過說response as any[]編譯器不知道您的數組包含哪些對象。 它可能在運行時工作,因為 typescript 然后“找到”請求的屬性。 所以你應該做的是創建一個類/接口來定義你希望從你的 API 接收到的 object,然后解析對它的響應。

例子:

private async getActor(actor:string) {
const response = await this.searchActor.getActorImage(actor).toPromise();
const images = response as actorImage[];
let actPics = [];    
  for (var val of images) {
    actPics.push(val.thumbnailUrl)}                   

}

interface actorImage{
  thumbnailUrl: string   
}

您將response聲明為any類型的數組,這是不正確的。 response不是數組, response.value是數組。 any關鍵字告訴 typescript 不要打擾類型檢查。 文檔

在某些情況下,並非所有類型信息都可用,或者它的聲明會花費不適當的努力。 這些可能發生在沒有 TypeScript 或第 3 方庫的情況下編寫的代碼中的值。 在這些情況下,我們可能希望選擇退出類型檢查。 為此,我們將 label 這些值與任何類型

因此,快速而骯臟的解決方法是告訴 typescript response類型為any ,執行如下操作:

 private async getActor(actor:string) {
    const response = await this.searchActor.getActorImage(actor).toPromise()
    let actPics = []    
      for (var val of (response as any).value) {
        actPics.push(val.thumbnailUrl)}                   
  }

另一種可能更適合 Angular 的做事方式是創建 model 並將其用作您的類型。 這是一個精簡的 model:

export class ImageSearchResult {
    // you could/should type this as well instead of being an array of 
    // type any. It might be something like value: []ImageData;
    value: []any; 
}

然后,您使用 model 類型而不是任何類型:

 private async getActor(actor:string) {
    const response = await this.searchActor.getActorImage(actor).toPromise()
    let actPics = []    
      for (var val of (response as ImageSearchResult).value) {
        actPics.push(val.thumbnailUrl)}                   
  }

但更進一步,您的服務應該返回正確的類型。 輸入服務返回的數據不是使用服務的模塊的工作。 另外-我假設您要返回一個observable 為什么調用toPromise 讓我們創建一個服務 function,它使用 Angular 的 http 服務並返回一個正確類型的 observable。 你可能已經有了這樣的東西:

  import { HttpClient } from '@angular/common/http';
  
  constructor(private http: HttpClient) { }

  /**
   * Search for images by actor. Returns an observable of type ImageSearchResult.
   * @param actor The name of the actor you want to search
   */
  getActorImage(actor: string): Observable<ImageSearchResult> {
    // Refactor to appropriate http action type (post/push/etc) and url.
    return this.http.get<ImageSearchResult>(`https://my-api.com/actor-search?q=${actor}`);
  }

然后消費這個服務function:

private getActor(actor:string) {
  this.searchActor.getActorImage(actor).subscribe(response => {
    let actPics = []
    // No casing necessary, response is already correct type.
    for (var val of response.value) {
      actPics.push(val.thumbnailUrl)
    }
  });
}

最后,看起來您可能正在嘗試使用 Azure 圖像搜索 API。 在這種情況下,看看他們如何鍵入返回對象以獲得靈感 根據您項目的許可證,您可能只需導入該項目並將其模型與您的服務一起使用。

您錯誤地嘗試將response定義為數組。 Javascript Array顯然沒有value屬性或方法。 您需要改為定義以下接口。

export interface IResponse {
  currentOffset: number;
  instrumentation: any;
  nextOffset: number;
  queryContext: any;
  readLink: string;
  totalEstimatedMatches: any;
  value: Array<any>;
  webSearchUrl: string;
  _type: string;
}

在理想情況下,您還將為instrumentationqueryContexttotalEstimatedMatches以及包含在value數組中的 object 定義類似的接口,並使用它們而不是使用any

此外,您不需要顯式循環來從 object 獲取值數組。 您可以改用Array#map方法。

export interface IResponse {
  currentOffset: number;
  instrumentation: any;
  nextOffset: number;
  queryContext: any;
  readLink: string;
  totalEstimatedMatches: any;
  value: Array<any>;
  webSearchUrl: string;
  _type: string;
}

@Component({...})
export class SomeComponent implements OnInit, OnDestroy {
  private async getActor(actor:string) {
    const response: IResponse = await this.searchActor.getActorImage(actor).toPromise();
    let actPics: Array<string> = response.value.map(val => val['thumbnailUrl']);
  }
}

補充說明:

  1. 嘗試使用可觀察的 RxJS 而不將其轉換為 Promise。 Observables 提供了一系列優於 Promises 的優勢

  2. toPromise()方法將在 RxJS 7 中棄用,並將在 RxJS 8 中消失。

該錯誤是由於您將響應投射到“any []”而引起的。 => 你有 2 個解決方案:

  1. 您刪除鑄件(沒有必要):

    private async getActor(actor:string) { const {value} = await this.searchActor.getActorImage(actor).toPromise() const actPics = value.map(val => val.thumbnailUrl)
    }

  2. 您聲明一個接口,表示您的 API 響應的類型

你只需要改變類型

const response:{value:any[]}

或者

const response:any

兩者都可以

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM