Types vs Interfaces in Typescript

Feb 15, 2024

4 mins read

Published in

Understanding Types vs Interfaces in TypeScript

TypeScript, being a superset of JavaScript, adds static typing to the language, offering developers more robust tooling and better code organization· When it comes to defining custom types and structures, TypeScript provides two primary constructs: types and interfaces· While both serve similar purposes, they have distinct characteristics and use cases· In this blog post, we’ll explore the differences between types and interfaces in TypeScript, and when to use each·

Types in TypeScript:

Types in TypeScript allow developers to define aliases for existing data types or create new ones by combining existing types· They are versatile and flexible, enabling complex type definitions with unions, intersections, and conditional types·

Let’s start with some basic examples:

1
2
3
4
5
type UserID = number;
type Username = string;

let id: UserID = 123;
let username: Username = "john_doe";

In the above code, we’ve defined two types, UserID and Username, which alias the number and string types, respectively· We then use these types to declare variables id and username·

Types also support union and intersection types:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
type Status = "active" | "inactive";
type User = {
  id: number;
  username: string;
  status: Status;
};

let user: User = {
  id: 123,
  username: "john_doe",
  status: "active"
};

Here, Status is a union type representing either “active” or “inactive,” and User is an object type with properties id, username, and status·

Types can also be used with conditional statements:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
type Promotion = {
  discountPercentage: number;
} | {
  discountAmount: number;
};

function applyPromotion(promotion: Promotion) {
  if ("discountPercentage" in promotion) {
    // Apply percentage discount
  } else {
    // Apply fixed amount discount
  }
}

Interfaces in TypeScript:

Interfaces in TypeScript are similar to types but are primarily used to define object shapes· They provide a way to enforce a contract on the structure of objects·

Let’s define an interface for the User object from the previous example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
interface User {
  id: number;
  username: string;
  status: "active" | "inactive";
}

let user: User = {
  id: 123,
  username: "john_doe",
  status: "active"
};

Interfaces can extend other interfaces:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
interface AdminUser extends User {
  isAdmin: boolean;
}

let admin: AdminUser = {
  id: 456,
  username: "admin_user",
  status: "active",
  isAdmin: true
};

In this example, AdminUser extends the User interface, inheriting its properties while adding an additional isAdmin property·

Interfaces also support optional properties:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
interface Book {
  title: string;
  author: string;
  year: number;
  isbn?: string; // Optional property
}

let book: Book = {
  title: "The Great Gatsby",
  author: "F· Scott Fitzgerald",
  year: 1925
};

When to Use Types vs Interfaces:

  • Use Types:

    • When defining simple aliases for existing data types·
    • When creating union or intersection types·
    • When using conditional types·
    • When defining complex data structures that don’t necessarily represent objects·
  • Use Interfaces:

    • When defining the shape of objects, especially when they represent entities or data structures·
    • When needing to extend or implement existing shapes with additional properties·
    • When working with libraries or frameworks that heavily rely on interfaces for type checking·

In TypeScript, types and interfaces serve similar yet distinct purposes· Types are more versatile and can be used for various type definitions, including aliases, unions, and conditional types· Interfaces, on the other hand, are specifically tailored for defining object shapes and enforcing contracts on their structures· Understanding when to use each construct is crucial for writing clean, maintainable, and type-safe code in TypeScript· By leveraging the strengths of both types and interfaces, developers can effectively express the intended semantics of their code while benefiting from TypeScript’s powerful type system·

Sharing is caring!