Guides

TypeScript Interface vs Type: What's the Difference?

Ravi Menonยทยท6 min read

If TypeScript gives you both interface and type, and they can describe the same object, which one are you supposed to reach for?

It's the sofa-versus-couch of TypeScript. Ask ten developers and you'll get ten confident, contradictory answers โ€” and most of the time it genuinely doesn't matter, the way nobody's ever misunderstood you for saying "couch." But there are a few real differences, and knowing them turns a stylistic argument into a quick decision.

They overlap almost completely

For describing the shape of an object, interface and type are interchangeable. These two are equivalent in nearly every situation:

interface User {
  id: string;
  name: string;
}

type User = {
  id: string;
  name: string;
};

Both check the same way, both show up the same in editor tooltips, both can be extended and implemented. If your codebase is mostly describing API responses and data models โ€” objects with fields โ€” you can pick one and be consistent, and that consistency matters more than the choice itself.

Where type does more

type is an alias for any type, not just an object. That makes it the only option for several things interface can't express:

type Id = string;                 // alias a primitive
type Status = "open" | "closed";  // union
type Point = [number, number];    // tuple
type Nullable<T> = T | null;      // generic helper

Unions and tuples are the big ones. The moment you need "open" | "closed" or a value that's string | number, type is your answer โ€” interface simply has no syntax for it.

Where interface does more

interface has one capability type lacks: declaration merging. Declare the same interface twice and TypeScript merges the members:

interface Window { myApp: string; }
interface Window { myVersion: number; }
// Window now has both members

That sounds like a footgun, and inside your own app it usually is. But it's exactly how you augment types from a library or the DOM without editing their source โ€” which is why library authors tend to prefer interface for the object types they publish.

The verdict

Use type when you need a union, a tuple, or an alias for a primitive โ€” cases interface can't handle. Use interface when you're describing an object that other code will extend or that a library needs to augment. When it's a plain object shape and neither applies, pick one and stay consistent; the readability of a uniform codebase beats the marginal difference every time. The TypeScript team's own guidance is roughly this: prefer interface until you need a feature only type provides.

Stop hand-writing them from JSON

Here's where most of these types actually come from: an API response you're staring at, trying to transcribe by hand. Don't. Paste the response into a JSON to TypeScript converter and it generates the interface for you โ€” correct field names, inferred types, nested objects and all. If the JSON is minified or hard to read first, run it through a JSON formatter to indent it, or open it in a JSON viewer to click through the structure before you generate the types.

Generating the shape from real data also sidesteps the most common bug: a hand-written type that quietly disagrees with what the server actually sends. If you're still nailing down the format itself, what JSON is covers its value types, and JSON vs YAML compares it with the config format you'll meet next. Get the types from the data, keep them consistent, and the interface-versus-type debate shrinks back to what it really is โ€” mostly sofa versus couch.

Try the tools

Frequently Asked Questions

What's the difference between interface and type in TypeScript?

For describing the shape of an object they're almost interchangeable โ€” both type-check identically and both can be extended. The real differences are at the edges: type can also alias primitives, unions, and tuples, which interface cannot; and interface supports declaration merging, which type does not.

Should I use interface or type?

A widely used rule of thumb is to prefer interface for object shapes โ€” especially public ones other code will extend or augment โ€” and reach for type when you need something only it can express, like a union or tuple. When neither special case applies, pick one and stay consistent across the codebase.

Can type do unions and interface can't?

Yes. A union like "open" | "closed" or string | number can only be written with type; interface has no syntax for unions or tuples. The moment you need one, type is the answer.

What is declaration merging?

Declaration merging is a TypeScript feature where declaring the same interface twice combines their members into one. It's specific to interface (type can't do it) and is mainly used to augment types from a library or the DOM without editing their source.

How do I create a TypeScript type from JSON?

Paste the JSON into a JSON-to-TypeScript converter and it generates the matching interface โ€” field names, inferred types, and nested objects included. Generating from real data avoids the common bug of a hand-written type that silently disagrees with what the API actually returns.

RM

Ravi Menon writes for CodeUtilityKit, where the team builds free, privacy-first developer tools that run entirely in your browser. Every guide is written and reviewed by developers who use these tools daily.