codingstuff.io
ExploreTutorialsProblemsCS Subjects
Get Started
ExploreTutorialsProblemsCS Subjects
Get Started
codingstuff.io

Master the art of building software through interactive tutorials, real-world problems, and guided projects.

Pune, Maharashtra, India

codingstuffmail@gmail.com

Product

  • Explore
  • Tutorials
  • Problems
  • CS Subjects

Company

  • About
  • Contact
  • Privacy Policy
  • Terms & Conditions
  • Sitemap

© 2026 codingstuff.io. All rights reserved.

Built with ❤️ for developers everywhere

/
/
All Tutorials
🔷

TypeScript

29 / 60 topics
25Generics in TypeScript26Generic Functions27Generic Classes28Generic Interfaces29Type Constraints
Tutorials/TypeScript/Type Constraints
🔷TypeScript

Type Constraints

Updated 2026-05-15
10 min read

Type Constraints

Introduction

In TypeScript, generics provide a way to create reusable components that can work with a variety of types while maintaining type safety. However, sometimes you may want to restrict the types that can be used with a generic. This is where type constraints come in. Type constraints allow you to specify that a generic type must extend a certain interface or class, ensuring that only compatible types are used.

Concept

Type constraints are specified using the extends keyword after the generic type parameter. By doing this, you can ensure that the generic type has at least the properties and methods defined in the constraint. This is particularly useful when you want to access specific properties or methods on a generic type without causing type errors.

For example, consider a function that logs the length of an array. If you use a generic type parameter without constraints, TypeScript won't know if the type has a length property. However, by adding a constraint to ensure the type extends ArrayLike, you can safely access the length property.

Examples

Basic Type Constraints

Let's start with a simple example where we create a function that logs the length of an array:

TypeScript
1function logLength<T>(arr: T[]): void {
2console.log(arr.length);
3}
4
5logLength([1, 2, 3]); // Output: 3
6logLength(['a', 'b', 'c']); // Output: 3

In this example, the generic type T is constrained to be an array. However, if we try to pass a non-array type, TypeScript will throw an error:

TypeScript
1logLength('hello'); // Error: Argument of type 'string' is not assignable to parameter of type 'never[]'.

To fix this, we can add a constraint to ensure T extends ArrayLike&lt;T&gt;:

TypeScript
1function logLength<T extends ArrayLike<T>>(arr: T): void {
2console.log(arr.length);
3}
4
5logLength([1, 2, 3]); // Output: 3
6logLength('hello'); // Output: 5

Now, the function can accept both arrays and strings, as they both have a length property.

Advanced Type Constraints

Type constraints can also be used to enforce more complex conditions. For instance, you might want to ensure that a generic type has a specific method:

TypeScript
1interface HasPrint {
2print(): void;
3}
4
5function executePrint<T extends HasPrint>(obj: T): void {
6obj.print();
7}

In this example, the executePrint function requires that the generic type T implements the HasPrint interface. This ensures that any object passed to the function has a print method:

TypeScript
1class Document implements HasPrint {
2print(): void {
3 console.log('Printing document...');
4}
5}
6
7const doc = new Document();
8executePrint(doc); // Output: Printing document...

If you try to pass an object that does not implement the HasPrint interface, TypeScript will throw an error:

TypeScript
1class Image {
2display(): void {
3 console.log('Displaying image...');
4}
5}
6
7const img = new Image();
8executePrint(img); // Error: Argument of type 'Image' is not assignable to parameter of type 'HasPrint'.

Multiple Type Constraints

You can also apply multiple constraints by separating them with &. This ensures that the generic type satisfies all specified conditions:

TypeScript
1interface HasName {
2name: string;
3}
4
5interface HasAge {
6age: number;
7}
8
9function displayInfo<T extends HasName & HasAge>(person: T): void {
10console.log(`Name: ${person.name}, Age: ${person.age}`);
11}

In this example, the displayInfo function requires that the generic type T implements both HasName and HasAge interfaces:

TypeScript
1class Person implements HasName, HasAge {
2name: string;
3age: number;
4
5constructor(name: string, age: number) {
6 this.name = name;
7 this.age = age;
8}
9}
10
11const person = new Person('Alice', 30);
12displayInfo(person); // Output: Name: Alice, Age: 30

If the object does not satisfy both constraints, TypeScript will throw an error:

TypeScript
1class Employee implements HasName {
2name: string;
3
4constructor(name: string) {
5 this.name = name;
6}
7}
8
9const employee = new Employee('Bob');
10displayInfo(employee); // Error: Argument of type 'Employee' is not assignable to parameter of type 'HasName & HasAge'.

What's Next?

In the next section, we will explore Modules in TypeScript, which allow you to organize your code into reusable and maintainable modules. Modules help manage dependencies and improve the structure of larger applications.

Stay tuned for more advanced topics and best practices in TypeScript!


PreviousGeneric InterfacesNext Modules in TypeScript

Recommended Gear

Generic InterfacesModules in TypeScript