zok
zok

Reputation: 7882

Iterating with TypeScript

How do you iterate N times when during each iteration you only want to use the key (index) of the iteration? There’s no array to iterate through - you could create an array like [...Array(num)] and call map() or forEach() on it, but then how can you use the key in each iteration without using the item (which in this case would be undefined) and without the TypeScript compiler moaning about it:

item is declared but its value is never read

Is this a use case for the old for loop or can it be done in a simpler/safer way?

{[...Array(totalNum)].map((item: any, key: number) => {
    // if I console.log(item), tsc won't moan, but clearly not a solution
    return (
        <SomeComponent key={key}>
        </SomeComponent>
    )
})}

Upvotes: 1

Views: 414

Answers (2)

Alex Wayne
Alex Wayne

Reputation: 186984

I've had to do this a lot in my codebase, and I made a handy helper called mapTimes()

/** Returns an array of the return value of `fn` run `times` number of times. */
export function mapTimes<T>(times: number, fn: (index: number) => T): T[] {
  const arr: T[] = []

  for (let i = 0; i < times; i++) {
    arr.push(fn(i))
  }

  return arr
}

I basically just build an array with value of the same integer as its index. Then you pass a function to map over it.

Usage:

{mapTimes(totalNum, (key: number) => {
    return (
        <SomeComponent key={key}>
        </SomeComponent>
    )
})}

Upvotes: 1

CertainPerformance
CertainPerformance

Reputation: 370619

Adding a _ in front of the parameter to indicate that the non-use of the parameter is deliberate can solve the warning:

[...Array(totalNum)].map((_item, key) => {

(note that explicitly declaring the types of the parameters is not required; it just adds extra syntax noise here)

If you want to remove the unused parameter completely, you can iterate over the keys of the array with Object.keys:

Object.keys([...Array(totalNum)]).map((key) => {

Upvotes: 4

Related Questions