TypeScript course menu
TypeScript Interfaces: Defining Object Shapes, Extending and Merging
Learn TypeScript interfaces: describing object shapes, optional and readonly properties, methods, extending interfaces, declaration merging, implementing interfaces in classes, and the practical differences between interface and type.
On this page
An interface names the shape of an object. Interfaces are the traditional way to describe objects in TypeScript and are used widely in libraries and codebases.
Declaring an interface#
interface Product {
readonly id: string;
name: string;
price: number;
tags?: string[];
describe(): string;
}
const pen: Product = {
id: "P-1",
name: "Gel pen",
price: 20,
describe() {
return `${this.name} costs ₹${this.price}`;
},
};
console.log(pen.describe());Gel pen costs ₹20The body uses the same syntax as object types: optional ?, readonly, and methods.
Extending interfaces#
extends creates an interface that has all the members of another, plus its own:
interface Person {
name: string;
email: string;
}
interface Employee extends Person {
employeeId: number;
department: string;
}
interface Manager extends Employee {
reports: Employee[];
}
const ravi: Employee = { name: "Ravi", email: "ravi@example.com", employeeId: 7, department: "Design" };
const asha: Manager = {
name: "Asha",
email: "asha@example.com",
employeeId: 1,
department: "Engineering",
reports: [ravi],
};
console.log(`${asha.name} manages ${asha.reports.map((r) => r.name).join(", ")}`);Asha manages RaviAn interface can extend several others at once: interface Admin extends Employee, Auditor {}.
Declaration merging#
Two interface declarations with the same name in the same scope merge into one:
interface Settings {
theme: string;
}
interface Settings {
fontSize: number;
}
const s: Settings = { theme: "dark", fontSize: 16 };
console.log(s);{ theme: 'dark', fontSize: 16 }This is mainly useful for adding properties to types defined elsewhere, such as extending a library's types or adding a property to the global Window interface. Within your own code, it can be surprising, which is one reason some teams prefer type.
Classes can implement interfaces#
A class can promise to match an interface with implements. The compiler checks that it does:
interface Shape {
area(): number;
name: string;
}
class Square implements Shape {
name = "square";
constructor(private side: number) {}
}error TS2420: Class 'Square' incorrectly implements interface 'Shape'.Adding an area() method fixes it. This is covered in Abstract Classes and implements.
Interfaces for functions and indexable objects#
Interfaces can also describe callable objects and dictionaries, although type aliases are often simpler for those:
interface Comparator {
(a: number, b: number): number;
}
interface PriceList {
[item: string]: number;
}
const ascending: Comparator = (a, b) => a - b;
const prices: PriceList = { tea: 20, coffee: 35 };
console.log([3, 1, 2].sort(ascending), prices.coffee);[ 1, 2, 3 ] 35interface or type?#
Both are fine for object shapes, and teams pick a convention. A common one:
interfacefor object shapes, especially public ones that others might extend;typefor unions, tuples, function types and anything composed from other types.
Whatever you choose, be consistent within a project.
Practice#
Practice exercise
Create an interface Vehicle with make, model, year and a method age(currentYear: number): number. Extend it into ElectricVehicle with batteryKwh and rangeKm. Create one electric vehicle and print its age in 2026 and its range per kWh to one decimal place.
Show solution
interface Vehicle {
make: string;
model: string;
year: number;
age(currentYear: number): number;
}
interface ElectricVehicle extends Vehicle {
batteryKwh: number;
rangeKm: number;
}
const ev: ElectricVehicle = {
make: "Example Motors",
model: "City EV",
year: 2022,
batteryKwh: 30,
rangeKm: 315,
age(currentYear) {
return currentYear - this.year;
},
};
console.log(`${ev.model} is ${ev.age(2026)} years old`);
console.log((ev.rangeKm / ev.batteryKwh).toFixed(1), "km per kWh");City EV is 4 years old
10.5 km per kWhKey takeaway#
Finished this lesson?