Interfaces in TypeScript
Interfaces describe object shapes and are central to structural typing.
Defining shapes
interface User {
readonly id: number;
name: string;
email?: string; // optional
}
Extending interfaces
interface Timestamps { createdAt: Date; updatedAt: Date }
interface UserWithTimes extends User, Timestamps {}
Declaration merging
Multiple interface declarations with the same name merge their members.
interface Window { appVersion: string }
interface Window { theme: "light" | "dark" }
// Window now has both appVersion and theme
Prefer merging for ambient declarations; within app code, prefer single definitions for clarity.
Index signatures
interface Dictionary {
[key: string]: number; // all values must be number-compatible
}
Avoid overly broad index signatures; they weaken type safety.
Callable and construct signatures
interface Formatter { (x: unknown): string }
interface ServiceCtor { new (url: string): { request(path: string): Promise<unknown> } }
Interface vs type alias
- Interfaces can merge and are often used for public APIs
- Type aliases handle unions, intersections, conditional/mapped types
type Result<T> = { ok: true; value: T } | { ok: false; error: string };
Use whichever expresses the model more clearly.
Summary
- Use interfaces for object shapes and extension
- Reach for type aliases for unions and advanced type operations