Use TypeScript Generics to enhance your React components and make them reusable

Use TypeScript Generics to enhance your React components and make them reusable!

What is TypeScript Generics?

Generics allow us to have a dynamic type for our components. It gives us more flexibility when building components and allows better reusability for the consumers of the components.

Let's have a look at a simple example of Generics:

function returnWhatItGets<Type>(arg: Type): Type => arg;

The part where we write < Type> tells typescript that when we use this function, we will be able to insert a dynamic type that will serve as the Type of our argument (arg) and the Type of the return value of this function.

That is how it looks:

const numberOutput = returnWhatItGets<number>(5);

const stringOutput = returnWhatItGets<string>("hi");

Now that we're all on the same page with Generics, let's implement generics in our React component!

1 import React from 'react';
2
3 export type GenericComponentProps<Type> = {
4 data: Type[];
5 };
6
7 export function GenericComponent<Type>({ data }: 8GenericComponentProps<Type>) {
9 return (
10 <>
11 {data?.map((item: Type, index: number) => (
12 <ul key={index}>
13 {(Object.keys(data[0]) as Array<keyof Type>).map((key) => (
14 <li key={key.toString()}>{item[key]}</li>
15 ))}
16 </ul>
17 ))}
</>
);
}

It might not look very clear at first glance, but it's really straightforward. Let's go through the code line by line:

On line number 3, we define a Generic type for our component's props (Type).

In line 4, we assume that our props object will have the "data" property. Our data type will be an array of the dynamic Type we will initiate our component.

Moving forward to line 7, we define our functional component with the generic Type that will be passed down to the props object's Type.

Our data is an array with our custom Type, so in line 11, we begin mapping that array. For each object, we output an<ul> attribute.

Now we want to output all the properties values of the given object, so we turn our object to an array of its keys using the Object.keys method and map it to print the value for each property. Notice how we define the type for this array dynamically with the keyof syntax.

Now let's test our component:

<GenericComponent
   data={[
    { name: 'Nitsan', city: 'Harish' },
    { name: 'Abraham', city: 'Beer Sheva' },
   ]}
  />

That's it! We get all the benefits of typescript, such as auto-completion and type checking, while creating flexible and reusable components.

Using tools to keep track and build independent components, such as Bit, our users benefit significantly from such a flexible setup.

  • For more posts like this follow me on LinkedIn

  • I work as frontend & content developer for Bit - a toolchain for component-driven development (Forget monolithic apps and distribute to component-driven software).

23