Interfaces and Type Aliases
The API Contract That Saved Our Integration
// user-service.js
function getUser(id) {
return db.query('SELECT * FROM users WHERE id = ?', [id])
.then(user => {
// Sometimes we do this
return { firstName: user.first_name, lastName: user.last_name };
// Other times we forget and return raw DB fields
return user;
});
}interface User {
id: string;
firstName: string;
lastName: string;
email: string;
createdAt: Date;
}
interface UserResponse {
user: User;
metadata: {
lastLogin: Date;
status: 'active' | 'suspended' | 'deleted';
};
}
function getUser(id: string): Promise<UserResponse> {
// TypeScript won't let me return the wrong shape
return db.query('SELECT * FROM users WHERE id = ?', [id])
.then(row => ({
user: {
id: row.id,
firstName: row.first_name, // Explicit mapping
lastName: row.last_name,
email: row.email,
createdAt: new Date(row.created_at)
},
metadata: {
lastLogin: new Date(row.last_login),
status: row.status
}
}));
}Object Types
Inline Object Types
Object Type Inference
Interfaces: Defining Contracts
Basic Interface
Optional Properties
Readonly Properties
Interface Extension
Single Extension
Multiple Extension
Type Aliases
Basic Type Alias
Object Type Aliases
Union Type Aliases
Interfaces vs Type Aliases
Key Differences
My Decision Framework
Index Signatures
String Index Signature
Number Index Signature
Mixed Index Signatures
Nested Interfaces
Simple Nesting
Deep Nesting
Function Properties in Interfaces
Method Syntax
Property Syntax
Hybrid Types
Real-World Example: API Response Types
Practical Patterns from Production
1. Discriminated Unions with Interfaces
2. Builder Pattern
3. Configuration Pattern
Common Mistakes I Made
1. Over-Nesting
2. Using any in Interfaces
any in Interfaces3. Not Using Optional Properties
Your Challenge
Key Takeaways
What I Learned
Last updated