Generics is a very useful TypeScript feature to help us write reusable types. However, we do not always want our generics to accept all types. Sometimes our functions may require certain properties from the generics. In other words, we want to add constraints to the generics. This article is about how to use extends
keyword to constrain your generics.
First, let’s look at an example where constraints to the generics is not required:
The function returnInput
logs and returns the argument whatever type it is. It works fine because the function does not use any specific properties of the input. In real world, this is not always the case.
Consider the following example:
The function introduce
logs the name property of the argument and returns the argument. The interface Person
ensures that the argument has a name
property but it also sets its type to Person
. Even though newColleague
has also property age
, the type system believes that the return type of introduce is Person
which does not have the property age
and therefore throws an error.
To fix this problem, we will use generics to type the argument and the return value. As the function will log the property name
of the argument, we need to constrain the generics to accept only types with a property name
.
Let’s see how we can achieve this with the extends
keyword:
By using the extends
keyword, the generics now accepts only objects which satisfy {name: string}
and therefore ensures that the argument has a property name
.
You can also add multiple constraints to the generics by extending intersection types. The example above illustrates that the argument has to satisfy both the requirements of interface HasName
and HasAge
.
Conclusion
Using extends
keyword to add constraints to your generics can ensure the generics has what properties you need. This can help you write type safer code.