Interface vs Type Alias
In this page:
Basic Object Shapes
Both interfaces and type aliases can describe the exact same object structure, and for straightforward object shapes the two are largely interchangeable. The real differences only show up in more advanced usage.
Example: Basic Object Shapes
interface UserI { name: string; }
type UserT = { name: string };
const a: UserI = { name: "Kai" };
const b: UserT = { name: "Mira" };
console.log(a, b);
Extending and Combining
Interfaces grow through the extends keyword to inherit from another interface, while type aliases typically use the & intersection operator to combine multiple types together. Both approaches achieve a similar end result through different syntax.
Example: Extending and Combining
interface Animal { name: string; }
interface Dog extends Animal { breed: string; }
type AnimalT = { name: string };
type DogT = AnimalT & { breed: string };
const dog: DogT = { name: "Fido", breed: "Poodle" };
console.log(dog);
Union Types and Type Aliases
Type aliases can represent a union of several possible types directly, such as type Status = active | inactive, which interfaces cannot express on their own since an interface always describes a single object shape. This makes type aliases the natural choice for values with multiple possible forms.
Example: Union Types and Type Aliases
type Status = 'active' | 'inactive';
let status: Status = 'active';
console.log(status);
Declaration Merging
Multiple interfaces declared with the exact same name in the same scope are automatically merged together into one combined interface, a feature called declaration merging. Type aliases have no equivalent; redeclaring a type alias with the same name is simply a compile error.
Example: Declaration Merging
interface Box {
width: number;
}
interface Box {
height: number;
}
const box: Box = { width: 10, height: 20 }; // merged automatically
console.log(box);
Choosing Between Interface and Type
Interfaces tend to feel more natural for describing reusable, extensible object contracts, especially for public APIs meant to be extended by consumers. Type aliases are especially useful for unions, intersections, and other type compositions that interfaces can't express directly.
Example: Choosing Between Interface and Type
interface ApiUser { id: number; } // extensible public contract
type Result = { ok: true } | { ok: false }; // union, needs type alias
console.log({ id: 1 } as ApiUser, { ok: true } as Result);
Chapter Quiz — Complete all 7 topics to unlock
0/7 topics done
Complete these topics first: