One last point that we would like to raise about generics is the fact that you can define generic constraints to narrow down the set of generic types that you accept. This is done by using the extends keyword (for example, T extends SomeType).
This is useful when you only want to allow a specific subset of types to be passed as generic arguments. Thanks to generic constraints, you can be sure that the properties/methods you expect will be available.
The following is an example:
abstract class Recipe { constructor(public name: string, public ingredients: string[]) { } } class ItalianRecipe extends Recipe { } class FrenchRecipe extends Recipe { constructor(name: string, ingredients: string[], public chef:
string) { super(name, ingredients); } } class BrittanyRecipe extends FrenchRecipe { } // generic constraint function displayRecipe<T extends FrenchRecipe>(recipe: T): void { console.log(`This is a french recipe conceived by the following
chef: ${recipe.chef}`); // we know that it has the 'chef' property } const brittanyRecipe = new BrittanyRecipe("Crèpe Bretonne", ["Eggs", "Flour", "Salt", "..."], "Bertrand Denis"); const italianRecipe = new ItalianRecipe("Spaghetti Bolognese", ["Pasta", "Tomatoes", "Garlic", "Onions", "..."]); // displayRecipe(italianRecipe); // If you uncomment this line you'll get the following error: property 'chef' is missing displayRecipe(brittanyRecipe); // This is a french recipe conceived by the following chef: Bertrand Denis
In the preceding example, our generic displayRecipe function only accepts an argument that is of or extends the BrittanyRecipe type. Thanks to this constraint, we know that the chef property will be available on the given object.
You can actually go even further and define type parameters in your generic constraints; refer to the official handbook to find out more: https://www.typescriptlang.org/docs/handbook/generics.html.
If you want to learn more advanced concepts, you can check out the following article about covariance and contravariance: https://www.stephanboyer.com/post/132/what-are-covariance-and-contravariance.