For DevelopersDecember 24, 2024

How to Pass Interfaces as Arguments in TypeScript

Discover how to design and use TypeScript interfaces as arguments in functions for more robust code.

TypeScript is a strong programming language that extends JavaScript by introducing static types. This allows developers to identify mistakes earlier and enhance code quality. Interfaces are one of TypeScript's most significant features. In this blog, we'll look at what interfaces are, how to design them, and how to use them as parameters in methods. By the end, you'll have a good knowledge of how to use interfaces in TypeScript.

Join Index.dev to work on innovative TypeScript projects with top global companies.

 

Understanding Interfaces in TypeScript

Definition of Interfaces

An interface in TypeScript is a mechanism to specify the geometry of an object. It functions as a contract, specifying the attributes and methods an object should have. Interfaces do not include any implementation; they only describe the structure. This enables for a clear separation of the specification and implementation, making code easier to manage and read.

Basic Syntax of Interfaces

Creating an interface is simple. Here's a simple example of a user-defining interface:

interface User {
  name: string;
  age: number;
  email: string;
}

In this example, the user interface requires three properties: name, age, and email address. Each property has a certain type, such as string or integer.

Difference Between Interfaces and Types

TypeScript additionally lets you specify types with the type keyword. While both may specify object forms, there are a few distinctions. For example, interfaces may be extended, but types cannot be extended in the same way. Here's a basic comparison:

// Using an interface
interface Animal {
  species: string;
}

// Using a type
type Vehicle = {
  make: string;
};

In general, interfaces are recommended for specifying object forms, especially when they need to be extended or implemented as classes.

Explore More: How to Rename Fields in TypeScript While Preserving JSDoc Annotations

 

Defining an Interface

Creating an Interface

Let's look at how to develop an interface in further depth. Here's a more complicated user interface with a method:

interface User {
  name: string;
  age: number;
  email: string;
  greet(): void; // Method signature
}

This interface has a greet function that will not be implemented.

Optional Properties in Interfaces

Sometimes you might wish to define characteristics that aren't needed. You may accomplish this by including a ? after the property name. Here's an example of optional property:

interface User {
  name: string;
  age?: number; // Optional property
  email: string;
}

In this situation, the age attribute is optional, thus an object can still comply with the User interface without it.

Read-Only Properties

You may use the readonly modifier to create attributes that cannot be changed after the object is created.

interface User {
  readonly id: number; // Read-only property
  name: string;
}

This implies that once an id is assigned, it cannot be modified.

 

Passing Interfaces as Arguments

Function Basics

TypeScript functions can receive parameters in the same way that JavaScript does. To improve type safety, you can define the types of these arguments.

Passing an Interface as a Parameter

To pass an interface as a parameter, just specify the interface type in the function signature. Here is an example of a function that accepts a user interface as an input.

function printUserInfo(user: User): void {
  console.log(`Name: ${user.name}`);
  console.log(`Email: ${user.email}`);
}

// Usage
const user: User = { name: 'John Doe', email: '[email protected]' };
printUserInfo(user);

In this case, the printUserInfo method expects a User object. TypeScript will check that the object supplied has the proper structure.

Using Multiple Interfaces in Functions

You may also combine numerous interfaces in a function. This is useful if you wish to blend different forms. Here's an example.

interface Address {
  street: string;
  city: string;
}

function displayUser(user: User, address: Address): void {
  console.log(`${user.name} lives at ${address.street}, ${address.city}`);
}

// Usage
const address: Address = { street: '123 Main St', city: 'Anytown' };
displayUser(user, address);

In this example, the displayUser method accepts a User and an Address interface as inputs.

 

Practical Examples

Example 1: User Registration Function

Let's write a simple method to emulate user registration. This function takes a User interface as an input and outputs a registration message.

function registerUser(user: User): void {
  console.log(`User registered: ${user.name}, Email: ${user.email}`);
}

// Usage
const newUser: User = { name: 'Jane Smith', email: '[email protected]' };
registerUser(newUser);

Example 2: Handling Events

You may also use interfaces to manage events. Here's an example interface for a mouse event:

interface MouseEvent {
  x: number;
  y: number;
  type: string;
}

function handleMouseEvent(event: MouseEvent): void {
  console.log(`Mouse ${event.type} at (${event.x}, ${event.y})`);
}

// Usage
const mouseEvent: MouseEvent = { x: 100, y: 200, type: 'click' };
handleMouseEvent(mouseEvent);

Example 3: Combining Interfaces

Sometimes you need to make a composite interface. For example, suppose you have a Car interface that incorporates attributes from both the User and the new Vehicle interface:

interface Vehicle {
  make: string;
  model: string;
}

interface Car extends Vehicle {
  owner: User;
}

function displayCarInfo(car: Car): void {
  console.log(`Car: ${car.make} ${car.model}, Owner: ${car.owner.name}`);
}

// Usage
const myCar: Car = {
  make: 'Toyota',
  model: 'Camry',
  owner: { name: 'Alice', email: '[email protected]' }
};

displayCarInfo(myCar);

 

Best Practices

Keep Interfaces Simple

When creating interfaces, keep things basic and focused. An interface should focus on a certain feature of your program rather than trying to cover everything.

Consistent Naming Conventions

Use clear and consistent naming standards for your interfaces. A typical pattern is to prefix interfaces with an uppercase I, such as IUser. This helps to differentiate interfaces from other kinds.

Use Extends for Reusability

You can extend interfaces to encourage code reuse. For example:

interface Admin extends User {
  permissions: string[];
}

function displayAdminInfo(admin: Admin): void {
  console.log(`${admin.name} has the following permissions: ${admin.permissions.join(', ')}`);
}

Explore More: 30 Essential Mobile Development Tools

 

Conclusion

In this blog, we looked at how to send interfaces as arguments in TypeScript. We discussed what interfaces are, how to construct them, and practical applications for utilizing them in functions. Using interfaces improves code clarity and maintainability, making TypeScript programs more robust.

For Developers:

Join Index.dev to work on innovative TypeScript projects with top global companies. Unlock high-paying remote opportunities and grow your skills today!

For Clients: 

Need top TypeScript developers who can write clean and maintainable code? Index.dev connects you with a global pool of vetted talent. Find the right talent, fast!

Share

Radhika VyasRadhika VyasCopywriter

Related Articles

For EmployersHow Specialized AI Is Transforming Traditional Industries
Artificial Intelligence
Artificial intelligence is changing how traditional industries work. Companies are no longer relying only on general skills. Instead, they are using AI tools and specialized experts to improve productivity, reduce costs, and make better decisions.
Ali MojaharAli MojaharSEO Specialist
For EmployersHow to Scale an Engineering Team After Series A Funding
Tech HiringInsights
Most Series A founders hire too fast, in the wrong order, and regret it by month six. Here's the hiring sequence that actually works, and the mistakes worth avoiding before they cost you a Series B.
Mihai GolovatencoMihai GolovatencoTalent Director