Skip to main content
Patrones avanzados de TypeScript: genéricos, tipos de utilidad y protectores de tipo

Patrones avanzados de TypeScript: genéricos, tipos de utilidad y protectores de tipo

Web DevelopmentDecember 26, 202518 min de lectura0 vistas
TypeScriptJavaScriptProgrammingTypesBest PracticesTutorial
Compartir:

TypeScript Patrones avanzados: genéricos, tipos de utilidad y protectores de tipo

TypeScript ha revolucionado el desarrollo de JavaScript al añadir la escritura estática. Pero para aprovechar realmente su poder, necesitas dominar patrones avanzados. Profundicemos en los genéricos, los tipos de servicios públicos y los protectores de tipo.

Por qué importa el TypeScript avanzado

Escribir TypeScript es fácil. Escribir bueno TypeScript que sea fácil de mantener, seguro y elegante requiere comprender patrones avanzados. Estos patrones te ayudan a:

  • 🎯 Capturar errores en el momento de la compilación
  • 📚 Mejorar la documentación del código
  • 🔄 Permitir una mejor refactorización
  • 💡 Mejorar el autocompletado del IDE

Genéricos: escribe una vez, úsalo en todas partes

Los genéricos te permiten escribir código reutilizable que funciona con varios tipos. ### Función genérica básica ```typescript function identity<T>(arg: T): T { return arg; }

const num = identity<number>(42); // type: number const str = identity<string>("hello"); // type: string const auto = identity(true); // type inferred: boolean # ## Restricciones genéricastypescript interface Lengthwise { length: number; }

function logLength<T extends Lengthwise>(arg: T): T { console.log(arg.length); return arg; }

logLength("hello"); // ✅ Works logLength([1, 2, 3]); // ✅ Works logLength({ length: 10 }); // ✅ Works // logLength(42); // ❌ Error: number doesn't have length # ## Interfaces genéricastypescript interface Repository<T> { findById(id: string): Promise<T | null>; findAll(): Promise<T[]>; create(item: Omit<T, "id">): Promise<T>; update(id: string, item: Partial<T>): Promise<T>; delete(id: string): Promise<void>; }

interface User { id: string; name: string; email: string; }

class UserRepository implements Repository<User> { async findById(id: string): Promise<User | null> { // Implementation return null; }

async findAll(): Promise<User[]> { return []; }

async create(item: Omit<User, "id">): Promise<User> { const user: User = { id: "generated", ...item }; return user; }

async update(id: string, item: Partial<User>): Promise<User> { // Implementation return { id, name: "", email: "" }; }

async delete(id: string): Promise<void> { // Implementation } } ## Tipos de utilidad: Navaja suiza de TypeScript # ## Parcial<T> - Hacer que todas las propiedades sean opcionalestypescript interface User { id: string; name: string; email: string; age: number; }

function updateUser(id: string, updates: Partial<User>) { // Can update any subset of properties }

updateUser("1", { name: "John" }); // ✅ updateUser("2", { email: "new@email.com" }); // ✅ updateUser("3", { name: "Jane", age: 30 }); // ✅ ### Seleccionar<T, K> - Seleccionar propiedades específicastypescript type UserPreview = Pick<User, "id" | "name">;

const preview: UserPreview = { id: "1", name: "John" // email and age not required }; # ## Omitir<T, K> - Excluir propiedades específicastypescript type UserCreate = Omit<User, "id">;

const newUser: UserCreate = { name: "John", email: "john@example.com", age: 30 // id is excluded }; # ## Registrar<K, T> - Crear tipo de objeto con claves específicastypescript type Role = "admin" | "user" | "guest";

type Permissions = Record<Role, string[]>;

const permissions: Permissions = { admin: ["read", "write", "delete"], user: ["read", "write"], guest: ["read"] }; # ## Tipo de devolución<T> - Tipo de devolución de función de extraccióntypescript function createUser() { return { id: "123", name: "John", email: "john@example.com" }; }

type User = ReturnType<typeof createUser>; // type User = { id: string; name: string; email: string; } ## Protecciones de tipo: seguridad de tipo de tiempo de ejecución ## # typeof Type Guard __CODE_BLOCK_8 __ ## # instancia de Type Guard __ CODE_BLOCK_9 __ ## # Protecciones de tipo personalizadas __ CODE_BLOCK_10 __ ## # Uniones discriminadas __ CODE_BLOCK_11__ ## Patrón avanzado: tipos condicionalestypescript type IsString<T> = T extends string ? true : false;

type A = IsString<string>; // true type B = IsString<number>; // false

// More practical example type NonNullable<T> = T extends null | undefined ? never : T;

type A = NonNullable<string | null>; // string type B = NonNullable<number | undefined>; // number ## Patrón avanzado: tipos mapeadostypescript type Readonly<T> = { readonly [P in keyof T]: T[P]; };

type Optional<T> = { [P in keyof T]?: T[P]; };

interface User { id: string; name: string; }

type ReadonlyUser = Readonly<User>; // { readonly id: string; readonly name: string; }

type OptionalUser = Optional<User>; // { id?: string; name?: string; } ## Ejemplo real: manipulador de respuesta APItypescript interface ApiResponse<T> { data?: T; error?: string; status: number; }

// Generic fetch wrapper async function fetchApi<T>(url: string): Promise<ApiResponse<T>> { try { const response = await fetch(url); const data = await response.json();

return {
  data,
  status: response.status
};

} catch (error) { return { error: error instanceof Error ? error.message : "Unknown error", status: 500 }; } }

// Type-safe usage interface User { id: string; name: string; }

async function getUser(id: string) { const response = await fetchApi<User>(/api/users/${id});

if (response.error) { console.error(response.error); return null; }

return response.data; // TypeScript knows this is User | undefined }

2. **Aprovecha los tipos de utilidad **: no reinventes la rueda
3. **Crear protectores de tipo personalizados **: mejorar la seguridad del tipo de tiempo de ejecución
4. **Usar sindicatos discriminados **: para una gestión estatal compleja
5. **Mantenga los tipos simples**: no haga demasiada ingeniería

## Errores comunes a evitar

❌ **Demasiado genérico**
```typescript
function process<T>(data: T): T {
  // Too generic, loses type information
  return data;
}

✅ ** Restringido correctamente **

Loading code...

Conclusión

Los patrones avanzados de TypeScript transforman tu código de "JavaScript escrito" a aplicaciones verdaderamente seguras y mantenibles. Domina estos patrones y escribirás mejor el código con menos errores.

Comience poco a poco, practique a menudo e incorpore gradualmente estos patrones en sus proyectos . ¡Tu futuro yo (y tus compañeros de equipo) te lo agradecerán! 🚀

Conectémonos

¿Listo para construir algo increíble juntos?

Envíanos un mensaje

🚀

Hablemos.

Cuéntame sobre tu proyecto.

Creemos algo juntos 🤘

Address

Faisalabad, Pakistan

Visit my social profile and get connected