TypeScript: Namespaces, módulos e importaciones

TypeScript: Namespaces, módulos e importaciones

Tabla de Contenido

Note

Décimo artículo de la serie sobre TypeScript. Organizaremos el código con namespaces y módulos ES: exportaciones nombradas, import, alias, export default y archivos barrel.

A medida que un proyecto crece, la organización del código deja de ser un detalle estético para convertirse en un factor de mantenibilidad. TypeScript ofrece dos mecanismos para estructurar el código: los namespaces —agrupadores internos— y los módulos ES —el estándar moderno basado en export e import. Analicemos cuándo usar cada uno.

Namespaces

Un namespace agrupa funciones, clases y variables relacionadas bajo un identificador común, exponiendo solo lo que marques con export:

namespace Validations {
  export const validateText = (text: string): boolean => {
    return text.length > 3
  }

  export const validateDate = (myDate: Date): boolean => {
    return !isNaN(myDate.valueOf())
  }
}

Validations.validateText('hola mundo')

Solo los miembros exportados (validateText, validateDate) son accesibles desde fuera mediante la notación Namespace.miembro.

Info

Los namespaces se usan cada vez menos en el desarrollo de aplicaciones, donde los módulos ES son el estándar. Sin embargo, siguen presentes como base interna de muchos frameworks y de archivos de definición de tipos (.d.ts).

Módulos: export e import

Los módulos son el mecanismo recomendado. Cada archivo es un módulo y expone su API con export; otros archivos la consumen con import. Para exportar, antepón export a la declaración:

// classes/Heros.ts
export class Hero {
  constructor(
    public name: string,
    public powerID: number,
    public age: number
  ) {}
}

Y para consumirla, usa import con desestructuración de los miembros nombrados:

// index.ts
import { Hero } from './classes/Heros'

const spiderman: Hero = new Hero('Spiderman', 100, 23)

Archivos barrel: centralizar exportaciones

Cuando una carpeta agrupa varios módulos relacionados, importarlos uno a uno desde rutas distintas se vuelve tedioso. Un archivo barrel —convencionalmente un index.ts dentro de la carpeta— reexporta todo desde un único punto de entrada:

// interfaces/index.ts
export { Hero } from './hero'
export { Villain } from './villain'

Esto permite importar múltiples miembros refiriéndote solo a la carpeta, lo que simplifica las rutas y desacopla a los consumidores de la estructura interna:

import { Hero, Villain } from './interfaces'
flowchart LR
    H[hero.ts] --> I[index.ts barrel]
    V[villain.ts] --> I
    I --> C[consumidor: import desde './interfaces']

Export alias

Un alias renombra un miembro al importarlo, lo que resuelve colisiones de nombres entre módulos distintos. Se usa la palabra clave as:

import { powers as poderes } from './data/powers'

console.log(poderes)

Export default

Una exportación por defecto designa el valor principal de un módulo. Se importa sin llaves y puede combinarse con importaciones nombradas en la misma línea:

// data/powers.ts
export default class Powers {
  /* ... */
}
export const powers = ['fuerza', 'velocidad']
import Powers, { powers as poderes } from './data/powers'

Powers corresponde a la exportación por defecto y poderes a una exportación nombrada renombrada con alias.

Tip

Prefiere las exportaciones nombradas frente a export default en bases de código grandes: facilitan el autocompletado, el refactoring automático y mantienen nombres consistentes entre el módulo y sus consumidores.

Del código a un bundle

Los módulos resuelven la organización en tiempo de desarrollo, pero el navegador necesita servir el resultado de forma eficiente. Empaquetadores como webpack combinan todos los módulos en uno o pocos archivos optimizados, resolviendo el grafo de dependencias que tejen tus import. TypeScript se integra en este flujo transpilando primero a JavaScript y dejando que el bundler se encargue del empaquetado final.

Conclusión

Estructurar el código es una decisión de arquitectura. Los namespaces agrupan elementos internos y persisten en definiciones de tipos, pero el estándar moderno son los módulos ES con export/import. Los archivos barrel centralizan las exportaciones, los alias resuelven colisiones de nombres y export default designa el valor principal de un módulo.

En el artículo final de la serie consolidaremos la configuración del compilador y la depuración de errores mediante tsconfig.json.

Etiquetas :