TypeScript Interface

Note: If you're new to TypeScript, check our Getting Started with TypeScript tutorial first.


In TypeScript, an interface is a way to define the shape of an object.

Here's a simple example of an interface. You can read the rest of the tutorial to learn more.

Example

interface Person {
    name: string;
    age: number;
}

const person: Person = {
    name: "Alice",
    age: 30,
};

console.log(person);

// Output: { name: 'Alice', age: 30 }

Here, the Person interface defines that a Person object should have a name (string) and an age (number).


Syntax of TypeScript Interface

An interface is defined using the interface keyword, followed by the interface name and a set of properties (with types).

interface InterfaceName {
    property1: type;
    property2: type;
    // More properties...
}

Interfaces are just a contract that helps to shape a value; they don't hold actual values themselves.

The actual values are assigned when we create an object based on that interface type. Let's take a look at an example.


Example 1: Car Interface

Let's define an interface named Car that describes the structure of a car object.

// Define an interface named Car
interface Car {
    brand: string;
    model: string;
    year: number;
}

// Create a Car object
const car: Car = {
    brand: "Tesla",
    model: "Model 3",
    year: 2022,
};

console.log(car);

Output

{ brand: 'Tesla', model: 'Model 3', year: 2022 }

The Car interface defines the structure of a car object, specifying that it should have brand, model, and year properties.

We then created a car object of the type Car, assigning actual values to the brand, model, and year.


Interface with Optional Properties

Some properties in an interface might not always be available. To handle this, TypeScript allows you to define optional properties by adding a ? after the property name. For example,

interface Car {
    brand: string;
    model: string;
    color?: string;  // Optional property
}

let myCar: Car = { brand: "Toyota", model: "Corolla" };
let anotherCar: Car = { brand: "Honda", model: "Civic", color: "Red" };

console.log(myCar);        
console.log(anotherCar);

Output

{ brand: 'Toyota', model: 'Corolla' }
{ brand: 'Honda', model: 'Civic', color: 'Red' }   

Here, we've the color property, which is optional (denoted by ?), meaning the object can either include or omit it.

The myCar object doesn't include color, while the anotherCar object does.


Frequently Asked Questions

Interface with readonly properties.

A readonly property can only be assigned once, typically during object initialization. After that, its value cannot be modified. For example,

// Define a Rectangle interface with read-only properties
interface Rectangle {
    readonly width: number;
    readonly height: number;
}

// Create a Rectangle object
let myRectangle: Rectangle = { width: 20, height: 30 };

// Error: Cannot assign to 'width' because it is a read-only property
myRectangle.width = 25;

Here, Rectangle defines width and height as readonly properties. Once the myRectangle object is created, the values of width and height cannot be changed.


Interface for Function Types

You can also use an interface to define the structure of a function, specifying the parameters and return type. For example,

interface Greet {
    (name: string): string;
}

const greet: Greet = (name) => `Hello, ${name}!`;

// Call the greet() function and log the result
console.log(greet("Selena"));

Output

Hello, Selena!

Here,

interface Greet { (name: string): string; }

creates a blueprint for a function. It says that the Greet function should take a name (a string) as a parameter and return a string.

Then, we create an actual function greet() that matches the blueprint:

const greet: Greet = (name) => `Hello, ${name}!`

The greet() function takes a name and returns a greeting message (eg, Hello, Selena!).


Interfaces with TypeScript Classes

In TypeScript, interfaces are also used to define the structure that a class must follow.

Interfaces can specify the properties and methods that a class should have, and the class implements that interface to ensure it follows the required structure.

For example,

// Define an interface for animals
interface Animal {
    name: string;
    sound: string;
    makeSound(): void;
}

// Dog class implements the Animal interface
class Dog implements Animal {
    name: string;
    sound: string;

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

    makeSound() {
        console.log(`${this.name} says: ${this.sound}`);
    }
}

// Create a Dog object and call makeSound()
let dog = new Dog("Buddy", "Woof");
dog.makeSound();  

// Output: Buddy says: Woof

At first, we defined the Animal interface, which has:

  • the name and sound (both string) properties
  • the makeSound() method that returns void

Then, we defined the Dog class that implements the Animal interface. This means the Dog class must include the name, sound properties, and the makeSound() method, as required by the Animal interface.


Use Case of Interfaces in Testing

Interfaces are especially useful in testing scenarios. For example, in a payment system, you could define an IPayment interface outlining the necessary properties and methods.

// Define a payment interface with an amount and a method
interface IPayment {
    amount: number;
    processPayment(): string;
}

// Implement the IPayment interface in a class
class TestPayment implements IPayment {
    amount: number;

    constructor(amount: number) {
        this.amount = amount;
    }

    processPayment() {
        return `Payment of $${this.amount} processed in test mode.`;
    }
}

// Create an instance and call the method
const testPayment = new TestPayment(100);
console.log(testPayment.processPayment());

Output

Payment of $100 processed in test mode.

In testing, the TestPayment class simulates payment behavior. By implementing the IPayment interface, it ensures consistency with the real payment class, reducing errors and improving reliability.

This approach guarantees the test class follows the same contract as the production class, ensuring the system works correctly in both real-world and testing scenarios.


Also Read:

Did you find this article helpful?

Our premium learning platform, created with over a decade of experience and thousands of feedbacks.

Learn and improve your coding skills like never before.

Try Programiz PRO
  • Interactive Courses
  • Certificates
  • AI Help
  • 2000+ Challenges