When to Use Type vs Interface in TypeScript

What you’ll build or solve

You’ll compare type and interface through practical examples and decide which one fits your use case. By the end, you’ll know when each is the better choice and how to avoid common confusion.

When this approach works best

This method works best when:

  • You are defining object shapes in a growing codebase.
  • You need unions, intersections, or advanced type composition.
  • You are contributing to a team project with style conventions.

This is not needed if you are writing very small scripts with minimal structure.

Prerequisites

  • TypeScript installed
  • Basic understanding of object types and unions
  • Ability to run tsc

Step-by-step instructions

Step 1: Use interface for object shapes that may grow

Use interface when modeling structured objects, especially if they may be extended later.

interfaceUser {
  id:number;
  name:string;
}

You can extend it:

interfaceAdminextendsUser {
  role:string;
}

Interfaces are ideal when:

  • You are describing objects.
  • You expect inheritance or extension.
  • You want declaration merging support.

What to look for

  • Clean extension using extends.
  • Better readability when modeling domain entities.

Step 2: Use type for unions and complex compositions

Use type when you need unions, intersections, or more advanced combinations.

typeStatus="pending"|"approved"|"rejected";

Interfaces cannot represent unions of primitives like this.

You can also create intersections:

typePerson= {
  name:string;
};

typeEmployee=Person& {
  employeeId:number;
};

Types work well when combining shapes or restricting values.

What to look for

  • Union types for limited sets of values.
  • Intersection types for combining multiple structures.

Step 3: Understand declaration merging

Interfaces support declaration merging. Types do not.

interfaceConfig {
  apiUrl:string;
}

interfaceConfig {
  timeout:number;
}

These two declarations merge into one:

interfaceConfig {
  apiUrl:string;
  timeout:number;
}

Trying the same with type results in an error.

Use interface when you need this merging behavior, often in library definitions.


Step 4: Compare flexibility

Both can describe object shapes:

typeProductType= {
  id:number;
  title:string;
};

interfaceProductInterface {
  id:number;
  title:string;
}

In simple object cases, they behave almost the same.

The difference appears when you need:

  • Unions → use type
  • Declaration merging → use interface
  • Complex mapped types → usually use type

Choose based on structure needs, not personal preference alone.


Examples you can copy

Example 1: Use interface for models

interfaceOrder {
  id:number;
  total:number;
}

interfacePaidOrderextendsOrder {
  paidAt:Date;
}

Good for structured domain models.


Example 2: Use type for union states

typeTheme="light"|"dark";

letcurrentTheme:Theme="light";

Good for restricted values.


Example 3: Combine multiple shapes

typeTimestamp= {
  createdAt:Date;
};

interfaceUser {
  id:number;
  name:string;
}

typeUserWithTimestamp=User&Timestamp;

Intersection makes composition simple.


Common mistakes and how to fix them

Mistake 1: Using interface for unions

What someone might try:

interfaceStatus="pending"|"approved";

Why it fails:

Interfaces cannot represent unions of primitive values.

Correct approach:

typeStatus="pending"|"approved";

Mistake 2: Using type when an extension is required

What someone might write:

typeUser= {
  id:number;
  name:string;
};

Then attempt to extend:

interfaceAdminextendsUser {
  role:string;
}

Why it may cause confusion:

This works, but mixing patterns inconsistently can reduce clarity in larger teams.

Correct approach:

Use interface consistently for extendable object models.


Mistake 3: Expecting type merging

What someone might do:

typeConfig= { apiUrl:string };
typeConfig= { timeout:number };

Why it breaks:

Type aliases cannot be redeclared.

Correct approach:

Use interface if merging behavior is needed.


Troubleshooting

If TypeScript reports duplicate identifier errors, check whether you redeclared a type alias.

If unions behave unexpectedly, confirm you are narrowing them before accessing specific properties.

If extension errors occur, verify the base type or interface is compatible.

If team style guides require one approach, follow project conventions for consistency.


Quick recap

  • Use interface for object models that may extend or merge.
  • Use type for unions and intersections.
  • Interfaces support declaration merging, types do not.
  • Both work for simple object shapes.
  • Choose based on the structure needs and project conventions.