Interfaces
Interfaces
Level 3 — Object Types & Interfaces A named contract that defines the shape of an object. It is the primary, most powerful way to define reusable object structures in TypeScript.
1. Prerequisites
- Object Types — The concept that Interfaces abstract.
2. Term Category
TypeScript Core Syntax (Object Interface Contracts): Interfaces define object structure contracts, supporting inheritance extension (extends) and automatic declaration merging.
3. Explanation
Environment Context
- Compile-Time
(1) Design Motivation — "Why did we design this?"
Writing inline Object Types ({ name: string, age: number }) inside every function signature is unreadable and violates the DRY (Don't Repeat Yourself) principle.
We need a way to declare a "Shape" once, give it a name, and reuse it everywhere. Interfaces solve this.
(2) Declaring and Using Interfaces
You declare an Interface using the interface keyword. By convention, interface names are written in PascalCase.
// 1. Declare the shape
interface User {
name: string;
age: number;
}
// 2. Reuse it everywhere!
function greet(user: User) { ... }
function save(user: User) { ... }
const myUser: User = { name: "Alice", age: 28 };
(3) Interface Inheritance (Extends)
The superpower of Interfaces is that they can inherit from other Interfaces using the extends keyword, exactly like Classes in Object-Oriented Programming.
This allows you to build complex shapes out of smaller, reusable pieces.
interface Animal {
name: string;
}
// Dog inherits 'name', and adds 'breed'
interface Dog extends Animal {
breed: string;
}
const myDog: Dog = { name: "Rex", breed: "German Shepherd" };
4. Common Mistakes & Pitfalls
Mistake 1: Declaration Merging (Accidental Overwrites)
The mistake: A developer creates interface Window { myGlobalFlag: boolean; } in their code.
Why it happens: Unlike Type Aliases, Interfaces in TypeScript support Declaration Merging. If you declare two interfaces with the exact same name in the same scope, TypeScript will merge them together!
Because Window is already a massive built-in TS interface representing the browser, the developer just successfully added myGlobalFlag to the global window object type!
Golden Rule: Declaration merging is powerful for augmenting global libraries, but it can cause incredibly confusing bugs if you accidentally reuse a common name. If you do not want merging, use type instead of interface.
Mistake 2: Attempting to Model Union Types using interface Syntax
The mistake: Writing interface Status = "open" | "closed"; (SyntaxError).
Why it's wrong: interface defines object shapes and class contracts. Primitive union types or tuple aliases must be declared using type alias syntax.
Incorrect:
// interface Status = "open" | "closed"; // ❌ SyntaxError
Fix:
type Status = "open" | "closed"; // Correct use of type alias for unions
Mistake 3: Confusing Interface Inheritance extends with Type Intersection &
The mistake: Using & with interface syntax expecting single inheritance hierarchy optimization.
Why it's wrong: interface Child extends Parent provides better compiler performance and error messages than complex type intersection chains.
Incorrect:
type A = { a: number };
type B = { b: string };
type AB = A & B; // Type intersection
Fix:
interface A { a: number }
interface B extends A { b: string } // Interface inheritance
5. Practice Exercises
Exercise 1: Extending Interfaces with extends
Scenario:
Define a base Entity interface and extend it into a UserEntity interface.
Requirements:
- Create
EntitywithidandcreatedAt. - Extend
Entityto createUserEntitywithemail.
Answer
Implementation
interface Entity {
id: string;
createdAt: Date;
}
interface UserEntity extends Entity {
email: string;
role: "admin" | "user";
}
const user: UserEntity = {
id: "usr_100",
createdAt: new Date(),
email: "admin@example.com",
role: "admin"
};
Technical Explanation
interface Child extends Parentinherits all properties from the parent interface.- Enables clean OOP composition and interface inheritance hierarchies.
- Improves compilation performance compared to complex type intersections (
&).
Exercise 2: Implementing Interfaces in Classes
Scenario:
Create a class implementing a Printable interface contract.
Requirements:
- Define
Printableinterface withprint(): voidmethod. - Implement interface in
Invoiceclass.
Answer
Implementation
interface Printable {
print(): void;
}
class Invoice implements Printable {
constructor(public id: number, public amount: number) {}
print(): void {
console.log(`Invoice #${this.id}: $${this.amount}`);
}
}
Technical Explanation
class ClassName implements InterfaceNameverifies that the class satisfies the interface contract.- Ensures that required methods (
print()) and properties are present on class instances. - Standard object-oriented architecture pattern.
Exercise 3: Comparative Decision Matrix: interface vs type
Scenario:
Formulate an architectural selection matrix comparing interface against Type Aliases (type).
Requirements:
- Contrast declaration merging, extension syntax, object shape modeling, and union type support.
Answer
Implementation
interface vs type Selection Matrix:
- interface: Declaration merging SUPPORTED, extends syntax, best for object shapes & OOP contracts. Cannot represent primitives, unions, or tuples directly.
- type: Declaration merging UNSUPPORTED, intersection (&) syntax, supports primitive aliases, unions ('A' | 'B'), tuples, and mapped types.
Rule of Thumb: Prefer interface for public APIs & object shapes; use type for unions, primitives & utility computations.
Technical Explanation
- Interfaces are open and extensible via declaration merging and
extends. - Type aliases are closed and versatile for complex type mathematics and unions.
- Foundational architectural choice in TypeScript.
6. Related Terms
- Type Aliases (
type) — The alternative way to name a type. implementsKeyword — How Classes use Interfaces to enforce their own shape.- Structural Typing / Duck Typing — Related concept: Structural Typing / Duck Typing.
- Declaration Merging — Related concept: Declaration Merging.
- Index Signatures — Related concept: Index Signatures.
- Object Types — Related concept: Object Types.
- Optional Properties (
?) — Related concept: Optional Properties (?). - Readonly Properties (
readonly) — Related concept: Readonly Properties (readonly). thisTyping in Functions — Related concept:thisTyping in Functions.- Intersection Types (
&) — Related concept: Intersection Types (&). - Abstract Classes — Related concept: Abstract Classes.
- Declaration Files (
.d.ts) — Related concept: Declaration Files (.d.ts).
7. Key Takeaways
- Interfaces are named contracts that define the required shape of an object.
- They drastically improve code readability and reusability.
- Interfaces can inherit from one another using the
extendskeyword. - Interfaces uniquely support Declaration Merging, meaning declaring the same interface twice will combine their properties rather than throwing an error.
- Prefer
interfacefor defining object structures, andtypefor unions/advanced types.