Interfaces & Type Aliases
Interfaces and type aliases define the SHAPE of objects — what properties they must have and their types. Think of them as contracts that objects must fulfill.
Ensures every object of that 'shape' has required fields, catching missing or wrongly-typed data instantly. Makes APIs self-documenting.
For any object with multiple properties: component props, API responses, function parameters, database row shapes.
Use interface for object shapes (extensible, can be merged). Use type for unions, primitives, tuples, or when you need advanced type features.
📚Key Terms
Optional property (?)— Property that may or may not exist: name?: string
Readonly— Property that cannot be changed after creation: readonly id: number
Union type (|)— Value can be one of several types: string | number
Intersection type (&)— Value must satisfy ALL types: TypeA & TypeB
Literal type— Exact value as a type: 'admin' | 'user' instead of just string
Code Examples
#1interface — object contracts
// Basic interfaceinterface User {id: number; // requiredname: string; // requiredemail: string; // requiredrole?: "admin" | "user"; // ? = optional, literal union typereadonly createdAt: Date; // readonly = cannot change after creation}// Using the interfacefunction greetUser(user: User): string {return `Hello, ${user.name} (${user.role ?? "user"})`;}const u: User = {id: 1,name: "Ali",email: "ali@example.com",createdAt: new Date(),// role is optional so we can omit it};// u.createdAt = new Date(); // ❌ Error: cannot assign to 'createdAt' — readonly// Extending interfacesinterface AdminUser extends User {permissions: string[];lastLogin: Date;}// Implementing multiple interfacesinterface Serializable {toJSON(): string;}interface Printable {print(): void;}interface Document extends Serializable, Printable {title: string;content: string;}
#2type aliases — more flexible
// Type alias for primitives and unionstype ID = string | number;type Status = "active" | "inactive" | "pending";type Direction = "up" | "down" | "left" | "right";// Type alias for objects (similar to interface)type Point = {x: number;y: number;};// Intersection types — combine typestype Employee = {employeeId: number;department: string;};type UserEmployee = User & Employee; // must have ALL fields from both// Conditional types (advanced)type IsString<T> = T extends string ? "yes" : "no";type Result = IsString<string>; // "yes"// Key differences: interface vs type// ✅ interface: can be extended with 'extends', can be merged// ✅ type: can use unions (|), intersections (&), computed types// Best practice:// → Use 'interface' for object shapes you'll extend/implement// → Use 'type' for unions, primitives, tuples, computed types// Function typestype Formatter = (value: string) => string;const uppercase: Formatter = (s) => s.toUpperCase();// Callback typetype OnChange = (event: React.ChangeEvent<HTMLInputElement>) => void;
Practice This Concept
Open the playground, paste any example, and experiment. The best way to learn is by breaking things.
Open in Playground