• 2 min

How To Let a TypeScript Function Accept an Index Type as Parameter

How To Let a TypeScript Function Accept an Index Type as Parameter
Table of Content

If you got the error “Element implicitly has an ‘any’ type because expression of type ‘string’ can’t be used to index type” in TypeScript via TSLint or Visual Studio Code? Here is your solution 👍

It sometimes happens that you want to have a generic function to get a specific property from an array of key-value pairs. But how do you type that correctly in TypeScript?

Problem

Let’s see this example function. TSLint won’t accept this.

getGraphItemData.component.tsts
getGraphItemData(dataProp: string, data: Vaccination[]) : GraphDataItemModel[] {  return data?.map(    (item) => {      const { date } = item      const value =      return new GraphDataItemModel({          label: item.date,          value: item[dataProp] ?? 0      })    }  )}

You will get an error like “Element implicitly has an ‘any’ type because expression of type ‘string’ can’t be used to index type ‘Vaccination’.”.

The error is given because you can’t guarantee that the dataProp parameter has a property from the Vaccination interface. When we keep it a string type, it will give error's when a property is not found in the Vaccination interface.

Solution

The Vaccination interface looks like this.

vaccination.interface.tsts
export interface Vaccination {    location: string    date: string    vaccine?: string    source_url?: string    total_vaccinations?: number | null    people_vaccinated?: number | null    people_fully_vaccinated?: number | null    total_vaccinations_per_hundred?: number | null    daily_vaccinations_raw?: number | null    daily_vaccinations?: number | null    daily_vaccinations_per_million?: number | null    people_vaccinated_per_hundred?: number | null    people_partly_vaccinated_per_hunderd?: number | null    people_not_vaccinated_per_hunderd?: number | null    people_fully_vaccinated_per_hundred?: number | null    share_doses_used?: number | null    total_distributed_per_hundred?: number | null    total_distributed?: number | null}

So how can we correctly resolve this error and still use it like item[dataProp]?

getGraphItemData.component.tsts
getGraphItemData(dataProp: keyof Vaccination, data: Vaccination[]) : GraphDataItemModel[] {  return data?.map(    (item) => {      return new GraphDataItemModel({          label: item.date,          value: item[dataProp] ?? 0      })    }  )}

It’s super simple. Just use keyof Vaccination here. Via the keyof we can tell that we only accept properties from the Vaccination interface as a function parameter.

If you want to dive deeper into TypeScript, I highly recommend the story “Mastering TypeScript’s Mapped Types” by Jose Granja .

Conclusion

Learning the basics and advanced types of TypeScript will be very beneficial to prevent error’s in the browser. Do you like TypeScript? Or do you think it’s too much?


Thanks!

After reading this post, I hope you learned something new or are inspired to create something new! 🤗

If I left you with questions or something to say as a response, scroll down and type me a message. Please send me a DM on Twitter @DevByRayRay when you want to keep it private. My DM’s are always open 😁

RayRay

I’m Ray, a Frontend Developer since 2009 living in the Netherlands. I write about Frontend Development, JavaScript, TypeScript, Angular, CSS, VueJS and a lot more related topics.

Want to reach me for comments or questions on my blog? Send a DM on Twitter @DevByRayRay