Skip to content
⚠️ This article was written in 2018. Some content may be outdated.

TypeScript: interface vs type

When learning TypeScript, it's easy to wonder: both interface and type can define types — which one should you use?

Similarities

typescript
// interface
interface User {
  id: number;
  name: string;
}

// type alias
type User = {
  id: number;
  name: string;
};

// Both can:
// - Describe object structures
// - Optional properties with ?
// - Readonly properties
// - Be implemented by classes
// - Extend/intersect with each other

Key Differences

1. interface Supports Declaration Merging

typescript
interface Window {
  myProp: string;
}
interface Window {
  anotherProp: number;
}
// Automatically merged: { myProp: string; anotherProp: number }

// type cannot be redeclared:
type Foo = { a: string };
type Foo = { b: number }; // ❌ Error: duplicate identifier

This is useful for extending global types (like Window or Vue).

2. type Can Represent More Type Forms

typescript
// Union types (interface can't)
type Status = "pending" | "success" | "error";
type ID = number | string;

// Tuples
type Point = [number, number];

// Conditional types (interface can't)
type NonNullable<T> = T extends null | undefined ? never : T;

// Mapped types (both work, but type is more common)
type Optional<T> = { [K in keyof T]?: T[K] };

// Function types (both work; type is slightly more concise)
type Handler = (event: MouseEvent) => void;
interface Handler {
  (event: MouseEvent): void;
}

3. extends Syntax

typescript
// interface inheritance:
interface Animal {
  name: string;
}
interface Dog extends Animal {
  breed: string;
}

// type inheritance (via intersection):
type Animal = { name: string };
type Dog = Animal & { breed: string };

// interface and type can extend each other:
// interface A extends TypeB { ... }  // ✅
// type C = InterfaceD & { ... }       // ✅ (via intersection)

Use interface when:

  • Describing object/class structure (clearer semantics)
  • Declaration merging is needed (extending third-party types)
  • Public APIs (consumers can extend them)

Use type when:

  • Union types, tuples
  • Utility types (Conditional Types, Mapped Types)
  • Function types (slightly more readable)
typescript
// Project conventions in practice
// Describing data structures → interface
interface User {
  id: number;
  name: string;
}
interface ApiResponse<T> {
  code: number;
  data: T;
}

// Utility types → type
type Nullable<T> = T | null;
type Optional<T> = { [K in keyof T]?: T[K] };

MIT Licensed