Technology

Apptension Blog

How to use TypeScript Record Utility Type? Detailed guide

Hey, what's up 🤙?

If you're a TypeScript user then you've probably come across Utility Types. They are very useful and increase the readability and reusability of your code. Today I'm going to show you Record Utility Type with examples of how to use it in your projects. Let's go!

Let's say we have an app where the user can order food 🥙 from a complete stranger and we show this food in 2 different ways. Some of the products are immediately available, while others are yet to go on sale and have the coming soon label. Below I've attached an overview image of what these list items might look like.

Element available:

They look a little different, one has a box with information at the bottom, while the other has a box with information at the top, a darkened image, and the text COMING SOON.

We can program the display of these items in the simplest way using lots of ifs, creating very ugly, unusable code that no one will want to touch later. 🤢 What if we suddenly have to add a food type like unavailable or sold out. It would be a disaster.

Also, either that crap or... we can use Record! Creating a beautiful, reusable, easily extensible code that when someone sees it they will be in tears of delight 😍

You may also like: Flask vs. Django - which framework to choose?

How TypeScript Record Types work?

Let's start with the definition of TypeScript Record Utility from the documentation.

Record - Constructs an object type whose property keys are keys and whose property values are typed. This utility can be used to map the properties of a type to another type.

And an example:

interface CatInfo {
	age: number;
	breed: string;
}

type CatName = "miffy" | "boris" | "mordred";

const cats: Record<CatName, CatInfo> = {
	miffy: { age: 10, breed: "Persian" },
	boris: { age: 5, breed: "Maine Coon" };
	mordred: { age: 16, breed: "British Shorthair" },
};

cats.boris;

In the documentation, they show us that we can use the TypeScript Record Utility Type to create an object that contains cat names as keys, and requires CatInfo type data as values for those keys. This means that every object I find in the cats object must consist of the cat's name and information about that cat, throughout the object we have a data match, provided in a very clean and simple way.

We can achieve even better results when we use ENUM for this!

Let's go back to the example with the food list 🤓

We declare ENUM with the names of our categories for displaying items in the food list.

enum FoodListTypes {
	available = 'AVAILABLE',
	comingSoon = 'COMING_SOON',
}

Then the enum will be able to be extended with more entries.

Next, we retrieve our FoodList component, which has all the logic for displaying the food list in a particular way.

import {FoodList} from '../components'

And we declare the possible variants of FoodList, namely AvailableFoodList and ComingSoonFoodList:

const AvailableFoodList = (list: Food[]) => <FoodList 
	type={FoodListTypes.available} list={list} />
const CoomingSoonFoodList = (list: Food[]) => <FoodList 
	type={FoodListTypes.comingSoon} list={list} />

Our plan is to create a code that allows us, by entering only a specific password from ENUMA, to select the appropriate FoodList variant. And this is where Record 💥 comes into action.

Let's look at the code below:

const FoodLists: Record<FoodListTypes, (list: Food[]) => JSX.Element> = {
	[FoodListTypes.available]: AvailableFoodList,
	[FoodListTypes.comingSoon]: ComingSoonFoodList,
}

We create a FoodLists object that contains all possible FoodList variants. We give it a Record type, we give as a key the enum entries - FoodListTypes, and as values to the keys, we give a function that returns the appropriate list. It is so simple! 

Such code is incredibly easy to extend and we can easily add new FoodList types, as well as remove them!

You might be interested: Dive into Javascript deeper with an explanation of Object.Prototype and classes

Now we can use the FoodLists object to display the list currently selected by the user:

const CurrentFoodList = () => {
	const [currentFoodListType, setCurrentFoodListType] = useState(FoodListTypes.available)
	const [list, setList] = useState<Food[]>([])

	useEffect(() => {
		setList(useStore(currentFoodListType))
	}, [currentFoodListType, setCurrentFoodListType])


	return (
		<>
			<button onClick={() => setCurrentFoodListType(FoodListTypes.available)}>
      	Order
      </button>
			<button onClick={() => setCurrentFoodListType(FoodListTypes.comingSoon)}>
      	Coming Soon
      </button>

			[renderFoodList(list, currentFoodListType)}
		<>
	)
}

🤯 We have a simple component that displays two buttons and renders the currently selected list. The food list is retrieved on the fly from the stock based on the currently selected type to display, and the currently selected food type is selected by clicking on the appropriate button.

TypeScript Record Utility Type – conclusion

I hope I've helped you get familiar with an interesting use of the TypeScript Record Utility Type and that you won't be afraid to use it in your projects. With Record, we can easily make code reusable and easily extensible.

If you want to learn even more from me, I invite you to codingbrah.com 😎

Thank you for your attention and cheers!

Read more

4 Inspiring Augmented Reality Campaigns
AWS Elastic Beanstalk vs Google Kubernetes Engine
Kacper Szarkiewicz
Kacper Szarkiewicz
Frontend developer
Does it sound like we speak the same language?
Get in touch

How to use TypeScript Record Utility Type? Detailed guide

July 5, 2022
5
minutes read
audio description available
TL;DR

If you're a TypeScript user then you should know about Utility Types - readability and reusability friends of your code. In this article, we're showing you Record Utility Type with examples of how to use it in your projects.

0:00
0:00
How to use TypeScript Record Utility Type? Detailed guide
How to use TypeScript Record Utility Type? Detailed guide

Hey, what's up 🤙?

If you're a TypeScript user then you've probably come across Utility Types. They are very useful and increase the readability and reusability of your code. Today I'm going to show you Record Utility Type with examples of how to use it in your projects. Let's go!

Let's say we have an app where the user can order food 🥙 from a complete stranger and we show this food in 2 different ways. Some of the products are immediately available, while others are yet to go on sale and have the coming soon label. Below I've attached an overview image of what these list items might look like.

Element available:

They look a little different, one has a box with information at the bottom, while the other has a box with information at the top, a darkened image, and the text COMING SOON.

We can program the display of these items in the simplest way using lots of ifs, creating very ugly, unusable code that no one will want to touch later. 🤢 What if we suddenly have to add a food type like unavailable or sold out. It would be a disaster.

Also, either that crap or... we can use Record! Creating a beautiful, reusable, easily extensible code that when someone sees it they will be in tears of delight 😍

You may also like: Flask vs. Django - which framework to choose?

How TypeScript Record Types work?

Let's start with the definition of TypeScript Record Utility from the documentation.

Record - Constructs an object type whose property keys are keys and whose property values are typed. This utility can be used to map the properties of a type to another type.

And an example:

interface CatInfo {
	age: number;
	breed: string;
}

type CatName = "miffy" | "boris" | "mordred";

const cats: Record<CatName, CatInfo> = {
	miffy: { age: 10, breed: "Persian" },
	boris: { age: 5, breed: "Maine Coon" };
	mordred: { age: 16, breed: "British Shorthair" },
};

cats.boris;

In the documentation, they show us that we can use the TypeScript Record Utility Type to create an object that contains cat names as keys, and requires CatInfo type data as values for those keys. This means that every object I find in the cats object must consist of the cat's name and information about that cat, throughout the object we have a data match, provided in a very clean and simple way.

We can achieve even better results when we use ENUM for this!

Let's go back to the example with the food list 🤓

We declare ENUM with the names of our categories for displaying items in the food list.

enum FoodListTypes {
	available = 'AVAILABLE',
	comingSoon = 'COMING_SOON',
}

Then the enum will be able to be extended with more entries.

Next, we retrieve our FoodList component, which has all the logic for displaying the food list in a particular way.

import {FoodList} from '../components'

And we declare the possible variants of FoodList, namely AvailableFoodList and ComingSoonFoodList:

const AvailableFoodList = (list: Food[]) => <FoodList 
	type={FoodListTypes.available} list={list} />
const CoomingSoonFoodList = (list: Food[]) => <FoodList 
	type={FoodListTypes.comingSoon} list={list} />

Our plan is to create a code that allows us, by entering only a specific password from ENUMA, to select the appropriate FoodList variant. And this is where Record 💥 comes into action.

Let's look at the code below:

const FoodLists: Record<FoodListTypes, (list: Food[]) => JSX.Element> = {
	[FoodListTypes.available]: AvailableFoodList,
	[FoodListTypes.comingSoon]: ComingSoonFoodList,
}

We create a FoodLists object that contains all possible FoodList variants. We give it a Record type, we give as a key the enum entries - FoodListTypes, and as values to the keys, we give a function that returns the appropriate list. It is so simple! 

Such code is incredibly easy to extend and we can easily add new FoodList types, as well as remove them!

You might be interested: Dive into Javascript deeper with an explanation of Object.Prototype and classes

Now we can use the FoodLists object to display the list currently selected by the user:

const CurrentFoodList = () => {
	const [currentFoodListType, setCurrentFoodListType] = useState(FoodListTypes.available)
	const [list, setList] = useState<Food[]>([])

	useEffect(() => {
		setList(useStore(currentFoodListType))
	}, [currentFoodListType, setCurrentFoodListType])


	return (
		<>
			<button onClick={() => setCurrentFoodListType(FoodListTypes.available)}>
      	Order
      </button>
			<button onClick={() => setCurrentFoodListType(FoodListTypes.comingSoon)}>
      	Coming Soon
      </button>

			[renderFoodList(list, currentFoodListType)}
		<>
	)
}

🤯 We have a simple component that displays two buttons and renders the currently selected list. The food list is retrieved on the fly from the stock based on the currently selected type to display, and the currently selected food type is selected by clicking on the appropriate button.

TypeScript Record Utility Type – conclusion

I hope I've helped you get familiar with an interesting use of the TypeScript Record Utility Type and that you won't be afraid to use it in your projects. With Record, we can easily make code reusable and easily extensible.

If you want to learn even more from me, I invite you to codingbrah.com 😎

Thank you for your attention and cheers!

Kacper Szarkiewicz
Kacper Szarkiewicz
Frontend developer
Download our free e-book and learn how to create DesignOps MVP for your organization 🚀
This field is required.
Thank you! You should receive the email with the e-book shortly!
Oops! Something went wrong while submitting the form.

You might also like