TypeScript provides two main ways to define the shape of data: interface and type. While they overlap significantly, there are important differences that affect when you should use each one.
Basic Syntax
Interface
interface User {
name: string;
age: number;
email?: string;
}
Type Alias
type User = {
name: string;
age: number;
email?: string;
};
For simple object shapes, they look nearly identical. The differences emerge in more advanced scenarios.
Key Differences
1. Extension / Inheritance
Interfaces use extends:
interface Animal { name: string; }
interface Dog extends Animal { breed: string; }
Types use intersections (&):
type Animal = { name: string; };
type Dog = Animal & { breed: string; };
2. Declaration Merging
Interfaces can be declared multiple times and are automatically merged:
interface Window { title: string; }
interface Window { close(): void; }
// Result: Window has both title and close()
Types cannot be re-declared — this would cause an error:
type Window = { title: string; };
type Window = { close(): void; }; // Error!
3. Union and Intersection Types
Only type can represent unions:
type Status = "active" | "inactive" | "pending";
type StringOrNumber = string | number;
Interfaces cannot express union types.
4. Tuple Types
Only type can define tuples:
type Coordinates = [number, number];
type NameAge = [string, number];
5. Mapped Types
Only type supports mapped types:
type Readonly<T> = { readonly [K in keyof T]: T[K] };
type Partial<T> = { [K in keyof T]?: T[K] };
6. Implements
Both can be used with class implements:
interface Printable { print(): void; }
class Report implements Printable { print() { /* ... */ } }
type Serializable = { serialize(): string; };
class Data implements Serializable { serialize() { return ""; } }
When to Use Interface
When to Use Type
string | number)[string, number])Best Practice
The TypeScript team recommends: "Use interface for public APIs and type for everything else." In practice, many teams pick one and use it consistently, only switching when a specific feature is needed.
Generate TypeScript interfaces from JSON automatically with our JSON to TypeScript converter.
