I am using for... in loop to iterate over an object using square brackets notation, TypeScript complains saying the following:
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)
I Know if this wasn't a loop I could tell TypeScript that "a" can be only certain values, but by using a loop I can't give types so I don't know what to do The problem is I think I can't tell Typescript that in event[a] "a" can take a few values only
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);
}
}
}
});
I am using the latest typescript with the latest nextJS framework, tsconfig set to aim for ES2015 ScreenShot of the code
CodePudding user response:
As the TypeScript error says, "The left-hand side of a 'for...in' statement cannot use a type annotation."
However, you can create a typed variable within the for...in
loop that does have a type, and use that to index your object.
Here's a modified version of the snippet in your question. I've added an empty data
variable and removed the querySplit
code because those parts don't have the necessary context in your snippet to resolve TypeScript errors.
You'll also note I had to replace your event[a]
code with a variable, because accessing the value using square bracket notation repeatedly doesn't work properly with TypeScript's type narrowing.
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
}
});
CodePudding user response:
I usually use the following pattern:
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]);
}