Skip to Content
TypeScript for Beginners: Catch Wrong Data Before It Runs
Beginner
0 likes
Courses
TypeScript for Beginners: Catch Wrong Data Before It Runs

Interfaces vs type Aliases: Pick One and Stick With It

See what interface and type share, where they differ, and set one rule for object shapes. After this, you stop switching between them by habit.

Course content

Sign in to save your progress.

Course Home

Skip ahead: If you already use both interface and type for object shapes and only need a rule for choosing, skip to "Pick one and write it down", then continue.

You will see two ways to name an object shape: interface and type. Tutorials mix them, teams argue about them, and beginners lose an afternoon wondering which is correct. Both work. The useful question is where they differ, and what to do about it.

The same shape, written twice

interface UserI {
  id: number;
  name: string;
}

type UserT = {
  id: number;
  name: string;
};

function show(user: UserI): string {
  return user.id + ": " + user.name;
}

const fromType: UserT = { id: 1, name: "Ana" };
console.log(show(fromType));
1: Ana

A UserT went into a function that asks for a UserI, and the compiler accepted it. TypeScript compares shapes, not names. If the properties match, the types are compatible. So the choice between the two is not about what the compiler allows you to pass around.

Extending

Both can build on another shape. The syntax differs.

interface Person {
  name: string;
}

interface Employee extends Person {
  role: string;
}

type Contact = Person & {
  email: string;
};

const e: Employee = { name: "Ana", role: "Analyst" };
const c: Contact = { name: "Ben", email: "ben@example.com" };
console.log(e.role, c.email);
Analyst ben@example.com

extends reads like English. The & on a type joins two shapes into one that has everything from both. For plain object shapes the result is the same.

Where they really differ

A type can name things that are not objects. An interface cannot.

type Status = "draft" | "sent" | "paid";
type Id = string | number;

const s: Status = "sent";
const id: Id = 42;
console.log(s, id);
sent 42

A union like "draft" | "sent" | "paid" needs type. You will use that constantly.

The other difference is the one that surprises people. Declare an interface twice with the same name and TypeScript merges the two declarations. Declare a type twice and it refuses.

interface Settings {
  theme: string;
}

interface Settings {
  fontSize: number;
}

const settings: Settings = { theme: "dark" };

type Limits = { max: number };
type Limits = { min: number };
merge.ts(9,7): error TS2741: Property 'fontSize' is missing in type '{ theme: string; }' but required in type 'Settings'.
merge.ts(11,6): error TS2300: Duplicate identifier 'Limits'.
merge.ts(12,6): error TS2300: Duplicate identifier 'Limits'.

The two Settings became one shape with theme and fontSize, so an object with only theme is missing a property. Merging is useful when a library lets you add to its types. In your own code it usually means two declarations in the same scope share a name by accident, and nothing warns you. The type duplicate is rejected immediately, which I would call the safer behaviour for everyday code.

⚠ Warning: If an error says a property is missing that you never wrote, search the file, and any script files compiled with it, for a second interface with the same name.

Pick one and write it down

There is no single correct answer. Many teams use interface for object shapes and type for unions and everything else. Others use type for all of it. Both are defensible. I could be wrong about which suits your team, but I am not wrong that mixing them without a rule makes the code harder to read.

A rule that works for beginners:

  1. Use type for unions, literals and anything that is not a plain object.
  2. Use one of the two for object shapes, and stay with it in the whole project.
  3. Write the choice in your project notes, so the next person does not reopen the argument.

💡 Tip: If you start with type for everything, you only have one thing to learn and you are never forced to switch. You can adopt interface later when a library needs it.

Common mistakes

  • Changing between interface and type file by file because a tutorial did it that way.
  • Reusing an interface name in two files and getting a merged shape you did not ask for.
  • Trying to write a union with interface. It is a syntax error.
  • Spending an hour on the choice. The difference matters less than being consistent.

If you skip this, you will end up with both styles in the same project, and the next developer will wonder what the difference is supposed to mean. If your project had one rule, what would you write at the top of the file?

About

See what interface and type share, where they differ, and set one rule for object shapes. After this, you stop switching between them by habit.

Duration
5 min
Last update
10/03/2026
Was this helpful?
​ 0 ​ 0

Comments (0)

Sign in to comment

No comments yet.