Open In App

TypeScript Generic Constraints

Last Updated : 25 Oct, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we are going to discuss Generic Constraints. TypeScript is known for its strong typing system. In TypeScript, If we require more control over our generic types, we use TypeScript Generic Constraints. We use Generic type constraints to specify limits on the types for generic type parameters. This helps us to determine that generic types extend or implement a specific type or contain specific properties.

What are Generic Constraints?

  • TypeScript Generics allows us to write reusable code by working with different data types. We can create functions, classes, or interfaces that can work with different data types.
  • Generics are defined as <T> and This type of T is used to define the type of function arguments, return values, etc.
  • Generic Constraints are used to specify limits to the types that can be used with generic type parameters.
  • This results in type checking and these conditions ensure that variables have a certain type of value before they are used in the context.
  • This check minimizes the occurrence of runtime errors.

Syntax:

function genericConstraintFunction<T extends GenericConstraintType>(param: T): void {
// ...
}

Where-

  • T is the generic type parameter.
  • `extends` GenericConstraintType specifies the constraint that Type T should be extending GenericConstraintType type.

Example 1: In this example consider we have an interface of sports and it contains a property called name of type string. We created a variable sport of type Sports and assigned the name “baseball”. We have a function called printSportName which expects an argument of type T. Now, to ensure that this Type T is of type Sports, we use the keyword ‘extends’ with Sports. This checks, if the arguments passed through the function, are of type Sports before the function execution.

 

Javascript




interface Sports {
    name: string;
}
  
function printSportName<T extends Sports>(sport: T): void {
    console.log(sport.name);
}
let sport: Sports = { name: "baseball" };
printSportName(sport);


Output:

baseball

Example 2: In this example , let learn how we use Property Key Constraints. This ensures generic type parameter to have certain properties or keys. This example is an extension of the example explained above. Here, we use ‘extends keyof’ to ensure that the value passed through K is of Type T and is a Key/Property of Type T.

Javascript




interface Sports {
    name: string;
    players: number;
}
  
function getNumberOfPlayers<T extends Sports, K extends keyof T>
(sport: T, players: K): T[K] {
    return sport[players];
}
  
let sport: Sports = { name: "baseball", players: 9 };
  
// 'players' is inferred as a number
let players: number = getNumberOfPlayers(sport, 'players');
console.log(`Number of Players are : ${players}`);


Output:

Number of Players are : 9

Example 3: In this example, we ensure that the generic type parameter class object implements a specific interface.

Javascript




interface Sports {
    name: string;
    players: number;
    getNumberOfGloves(): number;
}
  
class Baseball implements Sports {
    constructor(public name: string, public players: number) { }
  
    getNumberOfGloves(): number {
        return this.players * 2;
    }
}
  
function getNumberOfGloves<T extends Sports>(sport: T): void {
    console.log(`Number of Gloves required are : 
        ${sport.getNumberOfGloves()}`);
}
  
let baseball = new Baseball("baseball", 9);
getNumberOfGloves(baseball);


Output:

Number of Gloves required are : 18


Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads