0

This is the JSON Object that is stored locally

{
"data": {
    "John Doe": {"id":"1234", "username":"johndoe"},
    "Sia Xander": {"id":"1235", "username":"siax"}
  }
}

This is the TypeScript file that I have and I have created this function but it errors out

import { data } from "../Assets/data.json"

function createData(member: string, id: string, username: string) {
    return { member, id, username }
  }

interface Rows {
    member: string
    id: string
    username: string
  }

const rows: Rows[] = []

Object.keys(data).map(member =>
    rows.push(
      createData(
        member,
        data[member]["id"], //error
        data[member]["username"] //error
      )
    )
  )

I get the following error

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type "data": {
    "John Doe": {"id":string, "username":string},
    "Sia Xander": {"id":string, "username":string}
  }
}
 No index signature with a parameter of type 'string' was found on type

"data": {
    "John Doe": {"id": string , "username":string},
    "Sia Xander": {"id":string, "username":string}
  }
}

How do I tell TypeScript that "John Doe" and "Sia Xander" are strings? Or should I change the way I have made the JSON

1 Answer 1

1

Why it doesn't work:

This doesn't work because Object.keys() can return keys not present on the type of its argument. See this answer for more details.


What would work instead:

Instead, try using Object.entries:

Object.entries(data).map(([member, memberData]) =>
  rows.push(
    createData(
      member,
      memberData["id"],
      memberData["username"]
    )
  )
);

Object.entries returns key value pairs, so you don't need to do the lookup yourself. See the documentation for more information.


Also, you can use .map in a simpler way:

The way you're using .map works, but you can make it even simpler.

.map returns an array, so you don't need to use push().

Instead, try this:

const rows: Rows[] = Object.entries(data).map(([member, memberData]) =>
  createData(
    member,
    memberData["id"],
    memberData["username"]
  )
);
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the answer! I've been struggling for a while now, I am new to TypeScript. This solution is so clean and simple, just love it.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.