Generic Table component with React and Typescript

Display any kind of data using the same table component while enjoying the benefits of typescript features.

A very common use case is to be able to list multiple types of data using tables. This happens quite frequently in dashboards for instance.

For example, an e-commerce dashboard might want to display a table to list the items they have in their stock, and in another table, they want to display the list of client addresses.

When using React with Typescript we want to explore as much as possible the typing benefits it brings to us by creating a consistent component API. Which is both pleasant to work with and also powerful.

We’ll illustrate this by creating a simple Table component which provides us the basic functionality to have a generic table which deals primarily with 3 things:

  • Displaying primitives types (string, numbers, and booleans) out of the box.

Displaying primitive types out of the box

Let’s break down what’s happening here:

  • We defined the helpers objectValues which provides us a better way to get the object values with the correct typing.

So far, so good. One thing to notice here is the usage of the generic type T. In which we have added a constraint by doing T extends MinTableItem . This constraint requires that every item data has to have at least one property called id which can be a PrimitiveType.

If we test our Table, we can see the following:

Table Headers

Two things are needed here:

  • Define the TableHeaders type which states that for the headers prop we need to pass an object where the keys of this object, matches the fields of our data item. So for data item such as { id: string; name: string } the headers object would look like: { id: 'Id', name: 'Name' } .
  • Print the header values. No mistery here. We use the helper objectValues again to get the header values, map over it, and print it:

Notice in the following GIF how easy is to add headers to our table, as the editor can infer which keys we need to pass to the object and make sure we don’t forget to specify anything:

Custom rendering of data for advanced types, such as Object or Array

The last thing we want to add for our table is the hability to render data in anyway we like. For example, let’s say that in the ‘stock item’ data we have a new field called image which contains an url , a width and height property and we want to display that in a custom way.

Here is how we can do it:

  • Define a CustomRenders type responsible for defining the type of the object where we are sending the custom renders. It will get more clear in the test example below.
  • Define a new helper objectKeys . Which is similar to the objectVaues but instead return the array of keys of an object with the correct type infering.
  • Finally, update our component:

In this modification, we extract the rendering of rows to a function so it is a bit more clear what is going on.

  • We are iterating over the properties of each item by using the new helper objectKeys

and… Voilà

Full code is here:

I breath, I eat, I love and I code.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store