網站搜尋

在對象的 for...in 迴圈中的 TypeScript 類型


我正在使用 for...in 迴圈通過方括號符號來迭代一個物件,TypeScript 提示以下錯誤:

元素隱式具有 'any' 類型,因為無法使用 'string' 類型的表達式來索引 'EVENT' 類型。未在 'EVENT' 類型上找到帶有 'string' 類型參數的索引簽名。ts(7053)

我知道如果這不是一個迴圈,我可以告訴 TypeScript 「a」只能是某些特定的值,但因為使用了迴圈,我無法給予類型,所以我不知道該怎麼辦。問題是我認為我無法告訴 TypeScript 在 event[a] 中 「a」 只能取幾個值。

interface EVENT {
    imageURL: string;
    artist: string;
    location: string;
    city: string;
    seat: number;
    direction: string;
    country: string;
    type: string;
    date: string;
    tickets_available: number;
    tickets_left: number;
    id: string;
    description: string;
    price: number;
  }
data.filter((event: EVENT) => {
        // a = key of the object data
        for (let a in event) {
          let aSplit =
            typeof event[a] === "string"
              ? event[a].split(" ").map((element: string) => element.toLowerCase())
              : event[a];
          // b = word of searchTerm string
          for (let b of querySplit) {
            if (
              a === "artist" ||
              a === "location" ||
              a === "city" ||
              a === "country" ||
              a === "type"
            ) {
              if (aSplit.includes(b.toLowerCase())) matches.push(event);
            }
          }
        }
      });

我正在使用最新的 TypeScript 和最新的 NextJS 框架,tsconfig 設定為目標 ES2015,程式碼截圖

答案#1

我通常使用以下模式:

interface Foo {
    str: string,
    num: number,
}

const foo: Foo = {
    str: "one",
    num: 1,
};

let i: keyof Foo;
for (i in foo) {
    console.log(foo[i]);
}



遊樂場連結

答案#2

正如 TypeScript 錯誤所說,『for...in』語句的左側不能使用類型註解。

不過,你可以在 for...in 迴圈中建立一個具有類型的已型別變數,並使用它來索引你的對象。

這裡是你問題中的程式片段的修改版本。我已經新增了一個空的 data 變數,並移除了 querySplit 代碼,因為這些部分在你的程式片段中沒有足夠的上下文來解決 TypeScript 錯誤。

你也會注意到,我不得不將你的 event[a] 代碼替換成變數,因為使用方括號語法重複訪問該值在 TypeScript 的類型縮小中不能正常工作。

interface EVENT {
    imageURL: string;
    artist: string;
    location: string;
    city: string;
    seat: number;
    direction: string;
    country: string;
    type: string;
    date: string;
    tickets_available: number;
    tickets_left: number;
    id: string;
    description: string;
    price: number;
}

// Just creating an empty array so TypeScript doesn't complain about `data`
let data: EVENT[] = [];

data.filter((event: EVENT) => {
    // a = key of the object data
    for (let a in event) {
        // Create new typed variable for this iterations' value of `a`
        const key = a as keyof EVENT;
        // Look up `event[key]` once so TypeScript can narrow its type
        const value = event[key];

        let aSplit = typeof value === "string"
        ? value.split(" ").map((element: string) => element.toLowerCase())
        : value;

        // More stuff here
    }
});

TypeScript 遊樂場