What We Do

Company

Resources

Events

Blog

Free Consultation

ahoy@headway.io

(920) 309 - 5605

4 min
TypeScript Generics Explained - Creating Reusable Components
Subscribe

TypeScript Generics Explained - Creating Reusable Components

Chris Held
Development Lead

TypeScript is a great way to improve consistency and reliability in your JavaScript applications, as well as improve developer experience with static analysis tools.

### The problem

However, this does carry some overhead, and eventually, your application might start to carry a lot of types that can feel overwhelming.

### The solution

Thankfully, TypeScript has a few ways to refactor and reuse common types, and the one we’re going to cover today is generics.

## What are TypeScript generics?
A TS generic is a concept borrowed from other more strongly typed languages like C# and Java, and it allows a component to work across a variety of types, rather than a single one.


Here is a simple example of how that works in TypeScript:


   -- CODE line-numbers language-jsx --

   <!--

     function identity<T>(arg: T): T {

       return arg;

     }


     // output is typed as a string so returns a string

     let output = identity<string>("foo");

   -->


## Typescript generics examples

You can watch the video below or walk through the examples in this article at your own pace.


Let’s say you have a standard front-end application where users log in and perform actions on different things that are important to their business.

In this example, we’ll say those things are _Users_ and _Companies_.

Both _Users_ and _Companies_ are loaded into respective tables for viewing.

The types for that might look like this:


   -- CODE line-numbers language-jsx --

   <!--

     type UserListOptions = {

       pageSize: number;

       page: number;

       orderBy: 'name' | 'age';

       sortDirection: 'ASC' | 'DESC'

     };


     type UserListResult = {

       items: User[];

       page: number;

     };


     type CompanyListOptions = {

       pageSize: number;

       page: number;

       orderBy: 'name' | 'state';

       sortDirection: 'ASC' | 'DESC'

     };


     type CompanyListResult = {

       items: Company[];

       page: number;

     };


     // and on and on and on...

   -->


### There is an easy-to-spot pattern here

Each thing has a ListResult and ListOptions type that are almost identical.

With generics, we can refactor this concept into one type that will reduce a lot of copying and pasting:


   -- CODE line-numbers language-jsx --

   <!--

     type ListResult<T> = {

       items: Array<T>;

       page: number;

     }


     type ListOptions<T> = {

       pageSize: number;

       page: number;

       orderBy: T;

       sortDirection: 'ASC' | 'DESC'

     }


     type UserListResult = ListResult<User>;


     type UserListOptions = ListOptions<'name' | 'age'>;


     type CompanyListResult = ListResult<Company>;


     type CompanyListOptions = ListOptions<'name' | 'state'>;

   -->


### A short caveat on T

This is just a variable and can be named whatever makes sense to you, T is just a common standard that you will see a lot in documentation regarding generics.

The following code is just as valid and in this case makes the type much easier to read:


   -- CODE line-numbers language-jsx --

   <!--

     type ListOptions<OrderByOptions> = {

       pageSize: number;

       page: number;

       orderBy: OrderByOptions;

       sortDirection: 'ASC' | 'DESC'

     }

   -->


If you need multiple generics in a type you can comma-separate them:


   -- CODE line-numbers language-jsx --

   <!--

     type ListOptions<OrderByOptions, FilterByOptions> = {

       pageSize: number;

       page: number;

       orderBy: OrderByOptions;

       filterBy: FilterByOptions;

       filterByQuery: string;

       sortDirection: 'ASC' | 'DESC'

     }

   -->


If our types start to diverge we still have all the same options as before when using generics. Let's say we add a feature to deactivate users and want to add a filter for that in our UserListOptions.

We can create a type intersection while still abstracting away all of our common properties:


   -- CODE line-numbers language-jsx --

   <!--

     type UserListOptions = ListOptions<'name' | 'age'> & {isActive: boolean};

   -->


## More TypeScript resources

### Typescript Generics Docs

If you're interested in learning more about generics in TypeScript, check out the official docs here.

TypeScript Handbook - Generics

### TypeScript Course

If you're new and looking for a good course to learn TypeScript, Execute Program has a great set of courses here.

TypeScript Course - Execute Program

### Exploring Advanced TypeScript - Video

Explore some advanced TypeScript concepts such as utility functions and guards. If you're an adventurous JavaScript developer, you might find some value in this discussion too. Otherwise, it is the best fit for folks with some familiarity with TypeScript.

Advanced TypeScript Video


Asking Better Questions About Your Product

Download our free guide to begin implementing feedback loops in your organization.

By filling out this form, you agree to receive marketing emails from Headway.

Scaling products and teams is hard.

In this free video series, learn how the best startup growth teams overcome common challenges and make impact.

Scaling products and teams is hard.

In this free video series, learn how the best startup growth teams overcome common challenges and make impact.

You don’t need developers to launch your startup

In this free video series, learn proven tactics that will impact real business growth.

By filling out this form, you agree to receive marketing emails from Headway.

Make better decisions for your product

Dive deeper into the MoSCoW process to be more effective with your team.

By filling out this form, you agree to receive marketing emails from Headway.

A mindset for startup growth

In this free video series, learn the common mistakes we see and give yourself a greater chance for success.

By filling out this form, you agree to receive marketing emails from Headway.

The ultimate UX audit kit

Everything you need for a killer DIY audit on your product.

  • UX Audit Guide with Checklist
  • UX Audit Template for Figma
  • UX Audit Report Template for Figma

Enjoyed this post?

Other related posts

See all the ways we can help you grow through design, development, marketing, and more.

View All

Listen and learn from anywhere

Listen and learn from anywhere

Listen and learn from anywhere

The Manifest

Level up your skills and develop a startup mindset.
Stay up to date with the latest content from the Headway team.