Open In App

TypeScript Generic Constraints

Last Updated : 04 Sep, 2024
Summarize
Comments
Improve
Suggest changes
Like Article
Like
Share
Report
News Follow

In TypeScript, generic constraints restrict the types that can be used with a generic type by using the extends keyword. This ensures that the generic type adheres to a specific structure or interface, allowing access to certain properties or methods within the generic type.

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, the Sports interface has a name property. The printSportName function uses extends to ensure its argument conforms to the Sports type before execution.

// Define Sports interface with a name property
interface Sports {
    name: string;
}

// Function to print sport name, ensuring T extends Sports
function printSportName<T extends Sports>(sport: T): void {
    console.log(sport.name);
}

// Create a sport object of type Sports
let sport: Sports = { name: "baseball" };

// Call function with sport object
printSportName(sport);

Output:

baseball

Example 2: In this example, we use extends keyof to ensure that the generic type parameter K is a key of type T. This enforces that K is a valid property of T.

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.

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

TypeScript Generic Constraints - FAQs

Can you have multiple constraints on a generic type in TypeScript?

No, TypeScript does not allow directly specifying multiple constraints with extends. However, you can use intersection types to combine constraints, like T extends A & B.

How do generic constraints work with interfaces in TypeScript?

Generic constraints can enforce that a type parameter must match a certain interface, ensuring that the type parameter has the required properties or methods defined by the interface.

What happens if a type does not meet the generic constraint in TypeScript?

If a type does not meet the specified generic constraint, TypeScript will raise a compile-time error, preventing code that could cause runtime issues.

Can you use generic constraints with classes in TypeScript?

Yes, you can use generic constraints with classes to ensure that the type parameter extends a specific class or implements a certain interface.

Can generic constraints include primitive types in TypeScript?

Yes, generic constraints can include primitive types like number, string, and boolean, but they are more commonly used with objects, interfaces, or classes that define specific structures.


Next Article

Similar Reads

three90RightbarBannerImg