Interfaces and Types
Interfaces and Type Aliases allow you to create custom types to represent complex data structures.
Interfaces
Interfaces define the "shape" of an object:
typescript
interface User { name: string; email: string; age: number;} const user: User = { name: "Pedro", email: "pedro@email.com", age: 30};Optional Properties
Use ? for properties that may or may not exist:
typescript
interface Product { name: string; price: number; description?: string; // optional} // OK - description is optionalconst product1: Product = { name: "Laptop", price: 2500}; // Also OKconst product2: Product = { name: "Mouse", price: 89.90, description: "Wireless mouse"};Readonly Properties
Use readonly for properties that cannot be changed:
typescript
interface Config { readonly apiKey: string; readonly baseUrl: string; timeout: number;} const config: Config = { apiKey: "abc123", baseUrl: "https://api.example.com", timeout: 5000}; config.timeout = 10000; // OKconfig.apiKey = "xyz"; // Error! Readonly propertyExtending Interfaces
Interfaces can inherit from others:
typescript
interface Person { name: string; age: number;} interface Employee extends Person { role: string; salary: number;} const employee: Employee = { name: "Maria", age: 28, role: "Developer", salary: 8000};Type Aliases
Type aliases create a name for any type:
typescript
// Simple typetype ID = string | number; // Object typetype Point = { x: number; y: number;}; // Function typetype Operation = (a: number, b: number) => number; // Usagelet userId: ID = "abc123";userId = 42; // also valid const add: Operation = (a, b) => a + b;Interface vs Type
Both are similar but have some differences:
Interface Merging
typescript
// Interfaces with the same name are mergedinterface User { name: string;} interface User { age: number;} // User now has both 'name' and 'age'const user: User = { name: "Pedro", age: 30};Types Cannot Be Merged
typescript
// Error: Duplicate identifiertype User = { name: string;}; type User = { // Error! age: number;};Types Can Represent More
typescript
// Union typestype Status = "pending" | "approved" | "rejected"; // Mapped typestype Readonly<T> = { readonly [P in keyof T]: T[P];}; // Conditional typestype NonNull<T> = T extends null | undefined ? never : T;Intersection Types
Combine multiple types into one:
typescript
interface HasName { name: string;} interface HasAge { age: number;} type Person = HasName & HasAge; const person: Person = { name: "Pedro", age: 30};Index Signatures
For objects with dynamic keys:
typescript
interface Dictionary { [key: string]: string;} const translations: Dictionary = { hello: "olá", goodbye: "adeus", thanks: "obrigado"}; // Add new keys dynamicallytranslations.welcome = "bem-vindo";Conclusion
Interfaces and types are powerful tools for describing the shape of your data. In the next lesson, we'll learn how to type functions.