Both describe the shape of data and are often interchangeable, but they have different capabilities.
ts
interface User { name: string; age: number; }
type User2 = { name: string; age: number; };
Both describe the shape of data and are often interchangeable, but they have different capabilities.
interface User { name: string; age: number; }
type User2 = { name: string; age: number; };
typeinterfacetype ID = string | number; // unions
type Pair = [number, number]; // tuples
type Name = User["name"]; // indexed/mapped/conditional types
type Nullable<T> = T | null; // wrap any type
type is a general alias for any type — primitives, unions, tuples, mapped types. interface only describes object/function shapes.
interface can do that type can'tinterface Box { width: number; }
interface Box { height: number; } // declaration merging — both merge into one
// Box now has width AND height
Interfaces support declaration merging (multiple declarations combine) and are the idiomatic way to extend/augment, including augmenting third-party library types.
interface Admin extends User { role: string; } // interface
type Admin2 = User & { role: string }; // type uses intersection
A common convention: use interface for object shapes and public APIs (better error messages, extendable, mergeable), and type when you need unions, tuples, or other type operations. Pick one as the default for consistency — many teams default to interface for objects and reach for type only when its extra power is needed.