Imagina que cada vez que abres un archivo o una conexión de base de datos el compilador te recordara cerrar ese recurso automáticamente. Esa es la promesa del nuevo keyword using en TypeScript, y hoy lo vamos a desmenuzar.<\/p>
Foto por Mohammad Rahmani en Unsplash
Tabla de contenidos
Comparativa con
try...finallyy otras lenguas
¿Qué es using?
Introducido en TypeScript 5.2, using permite declarar variables cuyo ciclo de vida está ligado a un bloque de código. Cuando el bloque termina, el runtime invoca automáticamente el método dispose del objeto, liberando recursos como archivos, sockets o manejadores de memoria.
Foto por kenny cheng en Unsplash
Gestión explícita de recursos: patrones y buenas prácticas
Para aprovechar al máximo using, sigue estos principios:
Implementa la interfaz
Disposablecon un métododispose()que realice la limpieza.Limita el alcance del recurso al bloque donde realmente se necesita.
No mezcles lógica de negocio y liberación; mantén la responsabilidad de
disposeaislada.
A continuación un ejemplo de una clase FileHandle que sigue este patrón:
class FileHandle implements Disposable {
private readonly fd: number;
constructor(path: string) {
this.fd = Deno.openSync(path).rid;
}
read(): Uint8Array {
const buf = new Uint8Array(1024);
Deno.readSync(this.fd, buf);
return buf;
}
dispose(): void {
Deno.close(this.fd);
console.log('Archivo cerrado');
}
}
// Uso con using
using file = new FileHandle('datos.txt');
const contenido = file.read();
console.log(new TextDecoder().decode(contenido));
// Al salir del bloque, file.dispose() se llama automáticamenteComparativa con try...finally y otras lenguas
Antes de using, la forma tradicional en JavaScript era envolver el recurso en un try y garantizar su cierre en el finally. El código era más verboso y propenso a errores, especialmente cuando se olvidaba el finally o se lanzaban excepciones antes de llegar a él.
Lenguas como C# o Rust ya contaban con construcciones similares (using en C# y el trait Drop en Rust). La incorporación de este mecanismo en TypeScript cierra la brecha y nos brinda una API coherente en todo el ecosistema JavaScript.
Implementación práctica: ejemplo real
Supongamos que tienes una API que necesita abrir una conexión a una base de datos en cada petición. Con using puedes asegurarte de que la conexión se libere sin importar si la petición falla.
class DbConnection implements Disposable {
constructor(private readonly config: string) {
// Simulación de apertura de conexión
console.log('Conexión abierta');
}
query(sql: string): any {
// Simular consulta
return { rows: [] };
}
dispose(): void {
console.log('Conexión cerrada');
}
}
function handler(request: Request): Response {
using conn = new DbConnection('postgres://user:pass@host/db');
const result = conn.query('SELECT * FROM usuarios');
return new Response(JSON.stringify(result), { status: 200 });
// Si ocurre cualquier error, conn.dispose() se ejecuta automáticamente
}
Este patrón simplifica la gestión de recursos y reduce significativamente la superficie de errores relacionados con fugas de memoria o conexiones abiertas.
Conclusión
El keyword using llega en el momento justo para que los proyectos TypeScript adopten una gestión de recursos segura y concisa. Integra la interfaz Disposable, mantén los alcances limitados y olvídate de los tradicionales bloques try...finally. La próxima vez que abras un archivo, una socket o una conexión a DB, hazlo con using y deja que el compilador se encargue del resto.