Extending TypeScript Generics for Additional Type Safety | by Jason Byrne | Apr, 2022

Take your TypeScript polymorphism up a notch

Generics is among the extra difficult features of TypeScript, so child steps are necessary. On this article, I’ll do some fast examples of tips on how to do extra superior maneuvers by extending your generic varieties.

When you aren’t already aware of the idea of generics, I like to recommend you first learn my Brief Intro to TypeScript Generics article after which proceed right here.

Welcome again!

Let’s say we’ve got a category of kind Menu that appears like this:

Let’s additionally say that we’ve got the next forms of objects:

From the above we might instantiate a meals or a drink menu like this:

const drinkMenu = new Menu<Drink>();
const foodMenu = new Menu<Meals>();

The generics right here make sure that every a kind of menus can solely comprise the kind of merchandise they’re presupposed to. If I attempt to add a hamburger to the drink menu, then TypeScript goes to yell at me.

In order that’s figuring out nice! The issue is that I might additionally doubtlessly create a Waiter menu, and that might simply be plain bizarre.

const waiterMenu = new Menu<Waiter>();   // WTF?!?!?

So how can we forestall this? Straightforward! We are going to return to our authentic menu definition and add some constraints round our generic.

By including the extends Meals | Drink after our generic T we’re including an extra rule there. Solely varieties whose properties overlap with these two courses will likely be accepted.

Now if I attempt to instantiate a Waiter menu, my IDE goes to inform me {that a} menu of waiters is only a creepy factor to ask for, and it’s not welcome at this restaurant.

Boy! I have to be hungry. Let’s do one other meals instance. We’re going to create a sort that defines all the properties of a meals merchandise on our menu. After which we’re going to create a category that will get instantiated with these properties.

We add a get technique, which accepts a property argument, that may return the suitable worth of that property.

Now we’ve bought two main points right here. For one, once I name the get technique to search out out the value of that Eggs Benedict, my VS Code could have no clue which knowledge kind value must be, so it can simply contemplate it the dreaded any. And we all know that permitting any in your codebase is among the six lethal sins for TypeScript builders!

Secondly, we’re free to request any string because the property identify. For instance, we are able to ask for energy, and TypeScript will likely be completely tremendous with that. However, as everyone knows, you by no means ask what number of energy are in Eggs Benedict. Simply benefit from the deliciousness! Belief me, you don’t wish to know the calorie depend!!

However, I digress, our EggsBenedict object doesn’t have a energy property, so we’d ideally need our IDE to stop us from asking for it.

We are able to do higher than that, y’all! Let’s do this once more with a little bit assist from generics.

Don’t get overwhelmed. Let’s stroll by means of this. First, let’s zoom in on the keyof key phrase. This dynamically creates a sort for us that features all the properties of FoodProperties. After which our extends key phrase that we discovered earlier than tells TypeScript to constrain the attainable values of T to that listing of properties.

For our return worth, we’re utilizing FoodProperties[T], which says that based mostly on the property argument our return kind will match the sort outlined in FoodProperties for that property.

Now, once we attempt to do entry value and energy once more, it can know that value is a quantity and know that energy isn’t a legitimate property.

As you may already guess, you should utilize the identical idea to create a setter technique, which can solely settle for a worth of the right kind.

Our IDE is now completely satisfied and validating appropriately!

I hope this helps take your TypeScript polymorphism up a notch. Far more depth past this, however you’re in your method!

More Posts