TypeScript Interfaces

Introduction

In this chapter, we will explore interfaces in TypeScript. Interfaces define the structure of an object by specifying the properties and methods it must have. Understanding how to use interfaces is essential for writing robust and flexible TypeScript code that enforces type-checking and ensures consistency.

Table of Contents

  • Definition
  • Interface Syntax
  • Basic Interfaces
  • Optional Properties
  • Readonly Properties
  • Function Types
  • Indexable Types
  • Extending Interfaces
  • Implementing Interfaces in Classes
  • Complete Example with Output
  • Conclusion

Definition

An interface in TypeScript is a syntactical contract that an entity should conform to. It defines the shape of an object, including its properties and methods, without providing implementation. Interfaces ensure that a class or object adheres to a specific structure.

Interface Syntax

Syntax

interface InterfaceName {
  property: type;
  method(parameters): returnType;
}

Example

This example demonstrates a simple interface that defines the structure of a Person object.

interface Person {
  name: string;
  age: number;
  greet(): string;
}

Basic Interfaces

Interfaces can define the structure of an object by specifying the properties and methods it must have.

Example

This example demonstrates how to use an interface to define the structure of a Person object.

interface Person {
  name: string;
  age: number;
  greet(): string;
}

let person: Person = {
  name: "Ramesh",
  age: 25,
  greet: () => `Hello, my name is Ramesh.`
};

console.log(person.greet()); // Output: Hello, my name is Ramesh.

Output

Hello, my name is Ramesh.

Optional Properties

Properties in an interface can be marked as optional using the ? symbol. Optional properties are not required when creating an object that implements the interface.

Example

This example demonstrates an interface with optional properties.

interface Person {
  name: string;
  age?: number; // age is optional
  greet(): string;
}

let person1: Person = {
  name: "Ramesh",
  greet: () => `Hello, my name is Ramesh.`
};

let person2: Person = {
  name: "Suresh",
  age: 30,
  greet: () => `Hello, my name is Suresh.`
};

console.log(person1.greet()); // Output: Hello, my name is Ramesh.
console.log(person2.greet()); // Output: Hello, my name is Suresh.

Output

Hello, my name is Ramesh.
Hello, my name is Suresh.

Readonly Properties

Properties in an interface can be marked as readonly. These properties can be set once when the object is created, but cannot be modified afterwards.

Example

This example demonstrates an interface with readonly properties.

interface Book {
  readonly title: string;
  readonly author: string;
}

let book: Book = {
  title: "TypeScript Basics",
  author: "John Doe"
};

console.log(book.title); // Output: TypeScript Basics
console.log(book.author); // Output: John Doe

// book.title = "Advanced TypeScript"; // Error: Cannot assign to 'title' because it is a read-only property.

Output

TypeScript Basics
John Doe

Function Types

Interfaces can define the type of a function, including its parameters and return type.

Example

This example demonstrates an interface that defines a function type.

interface StringProcessor {
  (input: string): string;
}

let toUpperCase: StringProcessor = (input: string): string => {
  return input.toUpperCase();
};

console.log(toUpperCase("hello")); // Output: HELLO

Output

HELLO

Indexable Types

Interfaces can define indexable types, which are objects that can be indexed with a string or number.

Example

This example demonstrates an interface that defines an indexable type.

interface StringArray {
  [index: number]: string;
}

let myArray: StringArray = ["Alice", "Bob", "Charlie"];

console.log(myArray[0]); // Output: Alice
console.log(myArray[1]); // Output: Bob

Output

Alice
Bob

Extending Interfaces

Interfaces can extend other interfaces, inheriting their properties and methods. This allows for building complex types based on simpler ones.

Example

This example demonstrates how to extend interfaces.

interface Animal {
  name: string;
  makeSound(): void;
}

interface Dog extends Animal {
  breed: string;
}

let myDog: Dog = {
  name: "Buddy",
  breed: "Golden Retriever",
  makeSound: () => console.log("Woof!")
};

console.log(myDog.name); // Output: Buddy
console.log(myDog.breed); // Output: Golden Retriever
myDog.makeSound(); // Output: Woof!

Output

Buddy
Golden Retriever
Woof!

Implementing Interfaces in Classes

Classes can implement interfaces, ensuring that they adhere to the structure defined by the interface.

Example

This example demonstrates a class that implements an interface.

interface Animal {
  name: string;
  makeSound(): void;
}

class Dog implements Animal {
  name: string;
  breed: string;

  constructor(name: string, breed: string) {
    this.name = name;
    this.breed = breed;
  }

  makeSound(): void {
    console.log("Woof!");
  }
}

let myDog = new Dog("Buddy", "Golden Retriever");
console.log(myDog.name); // Output: Buddy
console.log(myDog.breed); // Output: Golden Retriever
myDog.makeSound(); // Output: Woof!

Output

Buddy
Golden Retriever
Woof!

Complete Example with Output

In this section, we will combine the examples into a single TypeScript file, compile it to JavaScript, and run it to see the output.

TypeScript Code

You can test the following code in the TypeScript Playground:

// Basic Interface
interface Person {
  name: string;
  age?: number; // optional property
  greet(): string;
}

let person1: Person = {
  name: "Ramesh",
  greet: () => `Hello, my name is Ramesh.`
};

let person2: Person = {
  name: "Suresh",
  age: 30,
  greet: () => `Hello, my name is Suresh.`
};

console.log(person1.greet()); // Output: Hello, my name is Ramesh.
console.log(person2.greet()); // Output: Hello, my name is Suresh.

// Readonly Properties
interface Book {
  readonly title: string;
  readonly author: string;
}

let book: Book = {
  title: "TypeScript Basics",
  author: "John Doe"
};

console.log(book.title); // Output: TypeScript Basics
console.log(book.author); // Output: John Doe

// Function Types
interface StringProcessor {
  (input: string): string;
}

let toUpperCase: StringProcessor = (input: string): string => {
  return input.toUpperCase();
};

console.log(toUpperCase("hello")); // Output: HELLO

// Indexable Types
interface StringArray {
  [index: number]: string;
}

let myArray: StringArray = ["Alice", "Bob", "Charlie"];

console.log(myArray[0]); // Output: Alice
console.log(myArray[1]); // Output: Bob

// Extending Interfaces
interface Animal {
  name: string;
  makeSound(): void;
}

interface Dog extends Animal {
  breed: string;
}

let myDog: Dog = {
  name: "Buddy",
  breed: "Golden Retriever",
  makeSound: () => console.log("Woof!")
};

console.log(myDog.name); // Output: Buddy
console.log(myDog.breed); // Output: Golden Retriever
myDog.makeSound(); // Output: Woof!

// Implementing Interfaces in Classes
class DogClass implements Animal {
  name: string;
  breed: string;

  constructor(name: string, breed: string) {
    this.name = name;
    this.breed = breed;
  }

  makeSound(): void {
    console.log("Woof!");
  }
}

let myDogClass = new DogClass("Buddy", "Golden Retriever");
console.log(myDogClass.name); // Output: Buddy
console.log(myDogClass.breed); // Output: Golden Retriever
myDogClass.makeSound(); // Output: Woof!

Conclusion

In this chapter, we covered interfaces in TypeScript, including how to define and use interfaces, optional and readonly properties, function types, indexable types, extending interfaces, and implementing interfaces in classes. We provided a complete example with its output to illustrate how these concepts work in TypeScript. Understanding interfaces is essential for writing robust and flexible TypeScript code that enforces type-checking and ensures consistency.

Comments

Spring Boot 3 Paid Course Published for Free
on my Java Guides YouTube Channel

Subscribe to my YouTube Channel (165K+ subscribers):
Java Guides Channel

Top 10 My Udemy Courses with Huge Discount:
Udemy Courses - Ramesh Fadatare