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.