Devkitrdevkitr
Converters

TypeScript Interfaces vs Types — When to Use Which

2025-12-108 min read

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


  • Defining object shapes that may need to be extended
  • Public API contracts (libraries, SDKs)
  • When you want declaration merging (extending third-party types)
  • Class shapes and OOP patterns
  • When the TypeScript handbook recommends "use interface until you need type"

  • When to Use Type


  • Union types (string | number)
  • Tuple types ([string, number])
  • Mapped or conditional types
  • Function type aliases
  • Complex type transformations
  • When composing with intersections is cleaner

  • 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.


    Related Articles

    Back to Blog