Intermediate Exercism • typescript

Interfaces & Type Aliases

Lesson Overview

Learn how to define complex data shapes and the differences between interfaces and type aliases.

Interfaces & Type Aliases

In TypeScript, there are two primary ways to define the “shape” of an object: Interfaces and Type Aliases. While they are very similar and can often be used interchangeably, they have distinct differences that are important to understand.

Interfaces

An interface is a powerful way to define a contract for an object. It describes what properties and methods an object should have.

interface User {
  id: number;
  name: string;
  email: string;
  isActive: boolean;
}

const newUser: User = {
  id: 1,
  name: "Rachmat Hidayat",
  email: "[email protected]",
  isActive: true
};

Optional Properties

You can mark a property as optional using the ? symbol.

interface User {
  id: number;
  name: string;
  middleName?: string; // Optional
}

Type Aliases

A type alias allows you to create a new name for any type, not just object shapes. This includes primitives, unions, and tuples.

type ID = string | number;
type Point = { x: number; y: number };

const userId: ID = 101;
const center: Point = { x: 0, y: 0 };

Interface vs. Type Alias

1. Extensibility (Merging)

Interfaces are open, meaning you can declare the same interface multiple times and TypeScript will merge them into one. Type aliases are closed and cannot be changed after they are defined.

interface Window {
  title: string;
}

interface Window {
  width: number;
}
// Merged Result: { title: string; width: number }

2. Heritage (Extending)

Both can extend other types, but the syntax is different.

// Interface extending interface
interface Animal { name: string }
interface Bear extends Animal { honey: boolean }

// Type extending type (using Intersection)
type AnimalType = { name: string };
type BearType = AnimalType & { honey: boolean };

Which should you use?

The general recommendation from the TypeScript team is to use Interfaces for object shapes whenever possible, especially if you expect the type to be extended. Use Type Aliases when you need to define unions, tuples, or non-object types.