TypeScript 在对象的 for...in 循环中键入

TypeScript type in a for... in loop on an object

我正在使用 for...in 循环来使用方括号表示法迭代一个对象,TypeScript 抱怨如下:

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'EVENT'. No index signature with a parameter of type 'string' was found on type 'EVENT'.ts(7053)

我知道如果这不是一个循环我可以告诉 TypeScript “a”只能是某些值,但是通过使用循环我不能给出类型所以我不知道该怎么做 问题是我想我不能告诉打字稿在事件[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 ScreenShot of the code

正如 TypeScript 错误所说,“'for...in' 语句的 left-hand 端不能使用类型注释。”

但是,您可以在 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 Playground

我通常使用以下模式:

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]);
}



Playground Link