Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{property: string, property: string }'

Viewed 308

My first day building something with React + TS.

I'm trying to make use of a 'dictionary' to convert a string into another.

import { eventDictionary } from '../utils/eventDictionary'

type Props = {
    id: string
    type: string
}

const GameCard: React.FC<Props> = ({id, type}) => {
    return (
        <div key={id}>
        <h3>{eventDictionary[type]}</h3> 
        <h3>{type}</h3> 
        </div>
    )
}

And this is the dictionary:

    bsk: "basketball",
    foot: "football",
    tenn: "tennis"
}

But I'm getting:

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ bsk: string; foot: string; tenn: string; }'.
  No index signature with a parameter of type 'string' was found on type '{ bsk: string; foot: string; tenn: string; }'.

What am I doing wrong?

2 Answers

Change the prop type to explicitly be a key in the object.

type Props = {
    id: string
    type: 'bsk' | 'foot' | 'tenn'
}

If the object keys aren't known in advance, and such a solution isn't usable, I'd recommend using a Map instead. Maps are a lot easier to manipulate than dynamically keyed objects in TypeScript.

import { eventDictionary } from '../utils/eventDictionary'
const eventMap = new Map(Object.entries(eventDictionary));
<h3>{eventMap.get(type)}</h3> 

Extending on @CertainPerformance s answer a more dynamic way would be

type Keys = keyof typeof eventDictionary;
type Values = typeof eventDictionary[Keys];

type Props = {
  id: string
  type: Values
}
Related