Volver a TypeScript Intermedio
Aumentación de Módulos y Fusión de Declaraciones
TypeScript permite extender tipos y módulos existentes sin modificar el código fuente original.
Fusión de Declaraciones
Múltiples declaraciones con el mismo nombre se fusionan en una:
// Fusionar interfaces
interface Window {
miAnalitica: { registrar: (evento: string) => void };
}
// Ahora window.miAnalitica está correctamente tipada
window.miAnalitica.registrar('page_view');
// Fusionar namespaces con funciones
function formatear(valor: number): string;
function formatear(valor: Date): string;
function formatear(valor: number | Date): string {
return valor instanceof Date ? valor.toISOString() : valor.toFixed(2);
}
namespace formatear {
export const moneda = (n: number) => `$${n.toFixed(2)}`;
export const porcentaje = (n: number) => `${(n * 100).toFixed(1)}%`;
}
formatear(3.14159); // "3.14"
formatear.moneda(9.99); // "$9.99"
Aumentación de Módulos
Extiende tipos de librerías externas:
// Aumentar Request de Express para incluir usuario
import 'express';
declare module 'express' {
interface Request {
usuario?: {
id: string;
correo: string;
roles: string[];
};
}
}
// Ahora en tu middleware de Express:
app.use((req, res, next) => {
req.usuario = { id: '123', correo: '[email protected]', roles: ['admin'] };
next();
});
app.get('/perfil', (req, res) => {
const { id, correo } = req.usuario!; // Tipado ✅
res.json({ id, correo });
});
Declaraciones Ambientales
Declara tipos para archivos JavaScript o variables globales:
// types/env.d.ts — Tipar variables de entorno
declare namespace NodeJS {
interface ProcessEnv {
NODE_ENV: 'development' | 'production' | 'test';
DATABASE_URL: string;
JWT_SECRET: string;
PORT?: string;
}
}
// types/global.d.ts — Declarar globales inyectadas en tiempo de ejecución
declare const __VERSION__: string;
declare const __FECHA_BUILD__: string;
// Usarlas de forma segura
console.log(`Versión: ${__VERSION__}`);
console.log(`BD: ${process.env.DATABASE_URL}`); // string tipado
Tipos de Utilidad en Profundidad
interface Usuario {
id: number;
nombre: string;
correo: string;
rol: 'admin' | 'usuario';
creadoEn: Date;
}
// Seleccionar campos específicos
type VistaUsuario = Pick<Usuario, 'id' | 'nombre'>;
// { id: number; nombre: string }
// Omitir campos
type CrearUsuarioDTO = Omit<Usuario, 'id' | 'creadoEn'>;
// { nombre: string; correo: string; rol: 'admin' | 'usuario' }
// Record — mapear claves a valores
type Permisos = Record<Usuario['rol'], string[]>;
// { admin: string[]; usuario: string[] }
// Extract / Exclude de uniones
type RolesAdmin = Extract<'admin' | 'usuario' | 'moderador', 'admin' | 'moderador'>;
// 'admin' | 'moderador'
type SinAdmin = Exclude<'admin' | 'usuario' | 'invitado', 'admin'>;
// 'usuario' | 'invitado'
// DeepPartial (tipo de utilidad personalizado)
type DeepPartial<T> = {
[K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];
};