TypeScript

TypeScript

Tutorial TypeScript: Exportación e importación de módulos

Aprende a usar named exports, default exports, re-exportación e import aliases en TypeScript para modularizar y organizar tu código eficazmente.

Aprende TypeScript y certifícate

Named exports

Los named exports (exportaciones con nombre) son uno de los mecanismos fundamentales en TypeScript para compartir código entre diferentes archivos. Este enfoque permite exportar múltiples valores desde un módulo, cada uno identificado por un nombre específico.

La sintaxis de los named exports es sencilla pero potente, permitiendo una organización modular del código que mejora la mantenibilidad y reutilización. Veamos cómo funcionan en detalle.

Sintaxis básica de named exports

Existen dos formas principales de crear named exports:

  • Exportación en línea: Se añade la palabra clave export directamente antes de la declaración.
  • Exportación agrupada: Se declaran los elementos primero y luego se exportan juntos al final del archivo.

Veamos ejemplos de ambos enfoques:

Exportación en línea:

// math.ts
export const PI = 3.14159;
export function sum(a: number, b: number): number {
  return a + b;
}
export class Calculator {
  multiply(a: number, b: number): number {
    return a * b;
  }
}

Exportación agrupada:

// utils.ts
const VERSION = '1.0.0';
function formatDate(date: Date): string {
  return date.toISOString().split('T')[0];
}
interface User {
  id: number;
  name: string;
}

// Exportación agrupada al final del archivo
export { VERSION, formatDate, User };

Importación de named exports

Para utilizar los elementos exportados, debemos importarlos en otros archivos usando la sintaxis de desestructuración:

// app.ts
import { sum, PI, Calculator } from './math';
import { VERSION, formatDate, User } from './utils';

console.log(PI);                    // 3.14159
console.log(sum(5, 3));             // 8

const calc = new Calculator();
console.log(calc.multiply(4, 2));   // 8

console.log(VERSION);               // 1.0.0
console.log(formatDate(new Date())); // "2023-05-15" (formato YYYY-MM-DD)

const user: User = {
  id: 1,
  name: 'Alice'
};

Importación selectiva

Una de las ventajas de los named exports es que podemos importar solo los elementos que necesitamos, lo que puede mejorar el rendimiento de nuestra aplicación:

// Solo importamos lo que necesitamos
import { sum } from './math';

console.log(sum(10, 5)); // 15

Renombrar durante la exportación

También podemos renombrar los elementos al exportarlos:

// config.ts
const apiKey = 'abc123';
const apiUrl = 'https://api.example.com';

// Renombramos al exportar
export { 
  apiKey as API_KEY,
  apiUrl as API_URL 
};

Luego, al importar, debemos usar los nuevos nombres:

import { API_KEY, API_URL } from './config';

console.log(API_KEY); // "abc123"

Exportación de tipos y interfaces

Los named exports son especialmente útiles en TypeScript para compartir tipos e interfaces:

// models.ts
export interface Product {
  id: string;
  name: string;
  price: number;
}

export type ProductId = string;

export enum ProductCategory {
  Electronics,
  Clothing,
  Books
}

Importación y uso:

import { Product, ProductCategory } from './models';

const laptop: Product = {
  id: '123',
  name: 'MacBook Pro',
  price: 1999
};

const category = ProductCategory.Electronics;

Exportación de valores por defecto

Podemos combinar named exports con valores por defecto en el mismo archivo:

// authentication.ts
export const TOKEN_KEY = 'auth_token';

export function validateToken(token: string): boolean {
  // Lógica de validación
  return token.length > 10;
}

// Función principal del módulo
export default function login(username: string, password: string): boolean {
  // Lógica de autenticación
  return username === 'admin' && password === 'secret';
}

Al importar, podemos combinar ambos tipos de exportaciones:

import login, { TOKEN_KEY, validateToken } from './authentication';

// Uso del export default
const isLoggedIn = login('admin', 'secret');

// Uso de named exports
localStorage.setItem(TOKEN_KEY, 'my-auth-token');
const isValid = validateToken('my-auth-token');

Exportación de todo un namespace

También podemos exportar todo un namespace como un named export:

// validation.ts
export namespace Validators {
  export function isEmail(value: string): boolean {
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return emailRegex.test(value);
  }
  
  export function isPhone(value: string): boolean {
    const phoneRegex = /^\d{10}$/;
    return phoneRegex.test(value);
  }
}

Importación y uso:

import { Validators } from './validation';

console.log(Validators.isEmail('user@example.com')); // true
console.log(Validators.isPhone('1234567890'));      // true

Buenas prácticas con named exports

  • Nombrado descriptivo: Usa nombres claros y descriptivos para tus exportaciones.
  • Cohesión: Agrupa en un mismo archivo exportaciones relacionadas entre sí.
  • Documentación: Añade comentarios JSDoc a tus exportaciones para mejorar la experiencia de desarrollo:
// api-client.ts

/**
 * Realiza una petición GET a la API
 * @param url - La URL del endpoint
 * @returns Una promesa con la respuesta
 */
export async function get<T>(url: string): Promise<T> {
  const response = await fetch(url);
  return response.json();
}

/**
 * Realiza una petición POST a la API
 * @param url - La URL del endpoint
 * @param data - Los datos a enviar
 * @returns Una promesa con la respuesta
 */
export async function post<T>(url: string, data: any): Promise<T> {
  const response = await fetch(url, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(data)
  });
  return response.json();
}

Los named exports son una herramienta esencial en el desarrollo modular con TypeScript, permitiendo crear código bien organizado, reutilizable y fácil de mantener.

Default exports

Los default exports (exportaciones por defecto) representan un mecanismo alternativo a los named exports en TypeScript para compartir código entre módulos. A diferencia de las exportaciones con nombre, cada archivo puede tener como máximo una exportación por defecto, lo que la convierte en la "exportación principal" del módulo.

Esta característica es especialmente útil cuando un módulo tiene un propósito principal claro o cuando queremos simplificar la importación de un componente o función que se utilizará con frecuencia.

Sintaxis básica de default exports

La sintaxis para crear una exportación por defecto es sencilla, solo necesitamos añadir la palabra clave export default antes de la declaración:

// calculator.ts
export default class Calculator {
  add(a: number, b: number): number {
    return a + b;
  }
  
  subtract(a: number, b: number): number {
    return a - b;
  }
}

También podemos exportar por defecto funciones, variables, o incluso valores literales:

// greet.ts
export default function greet(name: string): string {
  return `Hello, ${name}!`;
}

// config.ts
export default {
  apiUrl: 'https://api.example.com',
  timeout: 5000,
  retries: 3
};

// version.ts
export default '1.0.0';

Importación de default exports

La importación de exportaciones por defecto es más sencilla que la de named exports, ya que no requiere llaves y podemos asignarle el nombre que queramos:

// app.ts
import Calculator from './calculator';
import greet from './greet';
import config from './config';
import version from './version';

const calc = new Calculator();
console.log(calc.add(5, 3));        // 8

console.log(greet('Alice'));        // "Hello, Alice!"

console.log(config.apiUrl);         // "https://api.example.com"

console.log(`App version: ${version}`); // "App version: 1.0.0"

Observa que al importar, podemos usar cualquier nombre para referirnos a la exportación por defecto:

// Ambas importaciones son válidas y se refieren a la misma clase
import Calculator from './calculator';
import MathTool from './calculator';

const calc1 = new Calculator();
const calc2 = new MathTool();  // Mismo tipo, distinto nombre

Exportaciones por defecto anónimas

Una característica interesante de los default exports es que podemos crear exportaciones anónimas, lo que resulta útil para valores que solo se exportarán y no se usarán localmente:

// routes.ts
export default [
  { path: '/', component: 'Home' },
  { path: '/about', component: 'About' },
  { path: '/contact', component: 'Contact' }
];

// httpClient.ts
export default class {
  async get(url: string) {
    const response = await fetch(url);
    return response.json();
  }
  
  async post(url: string, data: any) {
    const response = await fetch(url, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(data)
    });
    return response.json();
  }
}

Exportación por defecto de valores existentes

También podemos declarar un valor primero y luego exportarlo por defecto:

// userService.ts
class UserService {
  getUsers() {
    // Implementación
    return [{ id: 1, name: 'John' }];
  }
  
  getUserById(id: number) {
    // Implementación
    return { id, name: 'John' };
  }
}

// Exportamos la clase ya definida
export default UserService;

Combinación de default y named exports

Un mismo archivo puede contener tanto exportaciones por defecto como exportaciones con nombre:

// api.ts
// Named exports
export const BASE_URL = 'https://api.example.com';
export function formatResponse(data: any) {
  return { success: true, data };
}

// Default export
export default class ApiClient {
  async fetch(endpoint: string) {
    const response = await fetch(`${BASE_URL}${endpoint}`);
    return formatResponse(await response.json());
  }
}

Para importar ambos tipos de exportaciones desde el mismo archivo:

// Importamos el default export y los named exports
import ApiClient, { BASE_URL, formatResponse } from './api';

const client = new ApiClient();
console.log(BASE_URL);  // "https://api.example.com"

Exportación por defecto de tipos e interfaces

En TypeScript, también podemos exportar tipos e interfaces por defecto:

// user.ts
export default interface User {
  id: number;
  name: string;
  email: string;
  isActive: boolean;
}

Y luego importarlos:

import User from './user';

const user: User = {
  id: 1,
  name: 'Alice',
  email: 'alice@example.com',
  isActive: true
};

Consideraciones y buenas prácticas

  • Coherencia en la nomenclatura: Aunque puedes importar un default export con cualquier nombre, es recomendable mantener coherencia usando el mismo nombre que sugiere el módulo.

  • Un default export por archivo: Cada archivo solo puede tener una exportación por defecto. Si intentas definir más de una, obtendrás un error.

  • Elección entre named y default exports:

  • Usa default exports cuando el módulo tiene un propósito principal claro.

  • Usa named exports cuando el módulo exporta múltiples valores relacionados.

  • Evita exportaciones anónimas en código complejo: Aunque las exportaciones anónimas son válidas, pueden dificultar la depuración y el seguimiento del código.

// Mejor evitar esto en código complejo
export default class {
  // Implementación...
}

// Preferible para mejor legibilidad y depuración
export default class AuthService {
  // Implementación...
}
  • Compatibilidad con JavaScript: Los default exports son compatibles con el sistema de módulos de JavaScript (ES modules), lo que facilita la interoperabilidad.

  • Documentación: Añade comentarios JSDoc a tus exportaciones por defecto para mejorar la experiencia de desarrollo:

/**
 * Cliente para interactuar con la API de usuarios
 * @class UserClient
 */
export default class UserClient {
  /**
   * Obtiene todos los usuarios del sistema
   * @returns {Promise<User[]>} Lista de usuarios
   */
  async getAll() {
    // Implementación
  }
}

Los default exports proporcionan una forma elegante de exportar la funcionalidad principal de un módulo, simplificando la sintaxis de importación y mejorando la legibilidad del código cuando se trabaja con componentes o clases que representan la esencia de un archivo.

Re-exportación

La re-exportación es una técnica poderosa en TypeScript que permite crear módulos intermediarios que agrupan y redistribuyen exportaciones de otros módulos. Esta funcionalidad facilita la organización del código en aplicaciones de gran escala, creando APIs más limpias y mejorando la estructura general del proyecto.

Concepto básico de re-exportación

La re-exportación permite tomar exportaciones (tanto named como default) de un módulo y volver a exportarlas desde otro módulo sin tener que crear nuevas implementaciones. Esto es especialmente útil para:

  • Crear puntos de entrada unificados para funcionalidades relacionadas
  • Ocultar la estructura interna de carpetas del proyecto
  • Simplificar las importaciones en el código cliente

La sintaxis básica utiliza la combinación de las palabras clave export e import:

// Re-exportamos todo desde otro módulo
export * from './otherModule';

Formas de re-exportación

Existen varias maneras de implementar la re-exportación en TypeScript:

1. Re-exportación completa

Re-exporta todas las exportaciones con nombre de otro módulo:

// models/index.ts
export * from './user.model';
export * from './product.model';
export * from './order.model';

Con esta técnica, todos los tipos, interfaces y funciones exportados desde los módulos individuales estarán disponibles a través del módulo índice:

// En otro archivo
import { User, Product, Order } from './models';
// En lugar de:
// import { User } from './models/user.model';
// import { Product } from './models/product.model';
// import { Order } from './models/order.model';

2. Re-exportación selectiva

Re-exporta solo elementos específicos de otro módulo:

// api/index.ts
export { get, post } from './http-client';
export { authenticate, logout } from './auth-service';

3. Re-exportación con renombrado

Re-exporta elementos cambiándoles el nombre:

// validation/index.ts
export { validate as validateEmail } from './email-validator';
export { validate as validatePassword } from './password-validator';

Esto es especialmente útil cuando dos módulos exportan funciones con el mismo nombre pero diferente funcionalidad.

4. Re-exportación de exportaciones por defecto

Podemos re-exportar una exportación por defecto como una exportación con nombre:

// components/Button.ts
export default function Button() {
  // Implementación
}

// components/index.ts
export { default as Button } from './Button';
export { default as Input } from './Input';
export { default as Checkbox } from './Checkbox';

Esto permite importar todos los componentes desde un único punto de entrada:

import { Button, Input, Checkbox } from './components';

5. Convertir una exportación con nombre en exportación por defecto

También podemos hacer lo contrario, convertir una exportación con nombre en una exportación por defecto:

// utils/formatters.ts
export function formatDate(date: Date) {
  return date.toISOString().split('T')[0];
}

// utils/index.ts
export { formatDate as default } from './formatters';

Ahora podemos importarla como una exportación por defecto:

import formatDate from './utils';

Patrones comunes de re-exportación

Patrón Barrel (Barril)

El patrón Barrel es uno de los usos más comunes de la re-exportación. Consiste en crear un archivo index.ts que re-exporta todos los elementos de una carpeta:

/models
  /user.model.ts
  /product.model.ts
  /order.model.ts
  /index.ts  <- Barrel file
// models/index.ts
export * from './user.model';
export * from './product.model';
export * from './order.model';

Este patrón simplifica enormemente las importaciones en proyectos grandes:

// Antes del patrón Barrel
import { User } from './models/user.model';
import { Product } from './models/product.model';
import { Order } from './models/order.model';

// Después del patrón Barrel
import { User, Product, Order } from './models';

Fachada de API pública

Otro patrón común es crear una fachada que expone solo las partes de tu API que deseas hacer públicas:

// api/internal/users.service.ts
export function getAllUsers() { /* ... */ }
export function getUserById() { /* ... */ }
export function _internalUserValidation() { /* ... */ }

// api/index.ts - Fachada pública
export { getAllUsers, getUserById } from './internal/users.service';
// No re-exportamos _internalUserValidation

Ejemplo práctico: Organización de una librería

Veamos un ejemplo completo de cómo organizar una pequeña librería utilizando re-exportaciones:

/src
  /components
    /Button
      Button.ts
      ButtonProps.ts
      index.ts
    /Input
      Input.ts
      InputProps.ts
      index.ts
    index.ts
  /utils
    /formatting
      dateFormatters.ts
      numberFormatters.ts
      index.ts
    /validation
      validators.ts
      index.ts
    index.ts
  index.ts

Implementación de los archivos:

// components/Button/ButtonProps.ts
export interface ButtonProps {
  text: string;
  onClick: () => void;
  disabled?: boolean;
}

// components/Button/Button.ts
import { ButtonProps } from './ButtonProps';

export function Button(props: ButtonProps) {
  // Implementación
}

// components/Button/index.ts
export * from './Button';
export * from './ButtonProps';

// components/index.ts
export * from './Button';
export * from './Input';

// utils/formatting/dateFormatters.ts
export function formatDate(date: Date): string {
  return date.toISOString().split('T')[0];
}

// utils/formatting/index.ts
export * from './dateFormatters';
export * from './numberFormatters';

// utils/index.ts
export * from './formatting';
export * from './validation';

// src/index.ts - Punto de entrada principal
export * from './components';
export * from './utils';

Con esta estructura, los usuarios de la librería pueden importar todo lo que necesitan desde un único punto:

import { Button, formatDate } from 'my-library';

Consideraciones de rendimiento

La re-exportación puede afectar al tree-shaking (eliminación de código no utilizado) en algunas configuraciones. Para mantener un buen rendimiento:

  • Evita re-exportar módulos completos si solo necesitas algunas partes
  • Considera usar re-exportaciones selectivas en lugar de export *
  • Asegúrate de que tu bundler (como webpack o Rollup) está configurado correctamente
// Mejor para tree-shaking
export { function1, function2 } from './module';

// Puede dificultar el tree-shaking
export * from './module';

Buenas prácticas

  • Mantén la coherencia: Adopta un enfoque consistente para la re-exportación en todo tu proyecto.
  • Documenta la estructura: Añade comentarios que expliquen la organización de tus módulos.
  • Evita la re-exportación excesiva: Demasiados niveles de re-exportación pueden dificultar el seguimiento del código.
  • Considera la visibilidad: Usa la re-exportación para ocultar detalles de implementación y exponer solo APIs públicas.
// api/index.ts
/**
 * API pública para operaciones de usuario.
 * Nota: Solo se exponen métodos seguros para uso externo.
 */
export { getUser, createUser, updateUser } from './user-service';
// No exponemos deleteAllUsers para evitar uso accidental

La re-exportación es una herramienta fundamental para crear estructuras de código mantenibles y APIs limpias en proyectos TypeScript. Cuando se utiliza correctamente, puede mejorar significativamente la organización del código y la experiencia de desarrollo.

Import aliases

Los import aliases (alias de importación) son una característica de TypeScript que permite renombrar módulos o elementos específicos durante su importación. Esta funcionalidad mejora la legibilidad del código, evita colisiones de nombres y facilita la refactorización de proyectos complejos.

Cuando trabajamos con aplicaciones de gran escala, es común encontrarnos con situaciones donde diferentes módulos exportan elementos con nombres idénticos o donde las rutas de importación son excesivamente largas. Los alias de importación ofrecen una solución elegante a estos problemas.

Renombrando importaciones individuales

La forma más básica de utilizar alias es renombrar elementos específicos durante la importación mediante la palabra clave as:

// Sin alias
import { formatDate, formatTime } from './formatters';

// Con alias
import { formatDate as formatDateString, formatTime as formatTimeString } from './formatters';

// Uso
const date = formatDateString(new Date()); // En lugar de formatDate

Este enfoque es particularmente útil en dos escenarios comunes:

  • Evitar colisiones de nombres: Cuando importamos elementos con el mismo nombre de diferentes módulos.
import { User as UserModel } from './models/user';
import { User as UserComponent } from './components/user';

// Ahora podemos usar ambos sin ambigüedad
const user: UserModel = { id: 1, name: 'John' };
const component = <UserComponent data={user} />;
  • Mejorar la claridad semántica: Cuando queremos que el nombre refleje mejor su uso en el contexto actual.
import { validateInput as validateEmail } from './validators/email';
import { validateInput as validatePassword } from './validators/password';

function registerUser(email: string, password: string) {
  if (!validateEmail(email)) {
    throw new Error('Invalid email');
  }
  
  if (!validatePassword(password)) {
    throw new Error('Invalid password');
  }
  
  // Resto de la implementación
}

Renombrando importaciones por defecto

También podemos asignar alias a las importaciones por defecto, aunque técnicamente ya estamos "nombrando" la importación al importarla:

// La importación por defecto ya es una forma de alias
import DefaultLogger from './logger';

// Podemos renombrarla si es necesario
import Logger from './logger';
// o incluso
import MyCustomLogger from './logger';

Sin embargo, cuando combinamos importaciones por defecto y con nombre, los alias pueden mejorar la claridad:

import DefaultApi, { get as httpGet, post as httpPost } from './api';

// Uso
const api = new DefaultApi();
const data = await httpGet('/users');

Alias para espacios de nombres (namespaces)

Cuando importamos todo un módulo como un espacio de nombres, también podemos asignarle un alias:

// Sin alias
import * as Validators from './validators';

// Con un alias más descriptivo
import * as FormValidators from './validators';

// Uso
if (FormValidators.isEmail(input)) {
  // Procesar email válido
}

Alias para rutas de importación complejas

En proyectos grandes, las rutas de importación pueden volverse largas y difíciles de mantener:

// Importación con ruta larga
import { UserService } from '../../../services/user/user.service';

Una solución común es configurar alias de rutas en el archivo tsconfig.json:

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@services/*": ["src/services/*"],
      "@models/*": ["src/models/*"],
      "@utils/*": ["src/utils/*"]
    }
  }
}

Con esta configuración, podemos simplificar nuestras importaciones:

// Importación simplificada con alias de ruta
import { UserService } from '@services/user/user.service';
import { User } from '@models/user';
import { formatDate } from '@utils/formatters';

Este enfoque no solo hace que el código sea más legible, sino que también facilita la refactorización, ya que si movemos los archivos dentro de la estructura de carpetas, solo necesitamos actualizar la configuración de los alias en lugar de todas las importaciones.

Combinando alias con desestructuración

Podemos combinar alias con la desestructuración de objetos para crear patrones de importación más expresivos:

// Importamos y renombramos múltiples elementos
import {
  validateEmail as isValidEmail,
  validatePassword as isStrongPassword,
  validateUsername as isValidUsername
} from './validators';

// Uso
if (isValidEmail(email) && isStrongPassword(password)) {
  // Proceder con el registro
}

Alias en re-exportaciones

Los alias también son útiles en las re-exportaciones, permitiendo crear APIs más coherentes:

// components/index.ts

// Re-exportamos con nombres más consistentes
export { default as Button } from './Button';
export { Input as TextInput } from './Input';
export { Checkbox as ToggleBox } from './Checkbox';

Ahora los consumidores pueden importar estos componentes con nombres más descriptivos:

import { Button, TextInput, ToggleBox } from './components';

Ejemplo práctico: Gestión de dependencias externas

Los alias son especialmente útiles cuando trabajamos con bibliotecas externas que pueden tener nombres confusos o inconsistentes:

// dependencies.ts
import * as _ from 'lodash';
import * as moment from 'moment';
import * as React from 'react';

// Re-exportamos con alias más descriptivos
export { _ as Utils };
export { moment as DateUtils };
export { React as UI };

En el resto de la aplicación:

import { Utils, DateUtils, UI } from './dependencies';

// Uso
const sorted = Utils.sortBy(items, 'name');
const formattedDate = DateUtils.format(new Date(), 'YYYY-MM-DD');
const element = UI.createElement('div', null, 'Hello World');

Este patrón centraliza la gestión de dependencias y proporciona una capa de abstracción que facilita los cambios futuros.

Buenas prácticas para el uso de alias

  • Consistencia: Establece convenciones claras para el uso de alias en tu proyecto.
// Ejemplo de convención: prefijo 'I' para interfaces
import { User as IUser } from './models';
import { UserComponent } from './components';

const userData: IUser = { id: 1, name: 'John' };
const component = <UserComponent user={userData} />;
  • Claridad sobre brevedad: Elige alias que mejoren la comprensión del código, no solo para acortar nombres.
// Mal uso de alias (demasiado corto, poco descriptivo)
import { AuthenticationService as auth } from './services';

// Mejor uso (descriptivo y claro)
import { AuthenticationService as AuthService } from './services';
  • Documentación: Cuando uses alias complejos, considera añadir comentarios explicativos.
// Importamos como API para mantener consistencia con otros servicios
// y evitar conflicto con el tipo UserService
import { UserService as API } from './services/user';
import type { UserService } from './types';
  • Evita alias innecesarios: No uses alias cuando no aportan valor.
// Innecesario y confuso
import { User as UserModel } from './models';

// Mejor mantener el nombre original si no hay conflicto
import { User } from './models';

Limitaciones y consideraciones

  • Compatibilidad con herramientas: Algunos analizadores de código o herramientas de refactorización pueden tener dificultades para rastrear alias.

  • Curva de aprendizaje: El uso excesivo de alias puede dificultar la comprensión del código para nuevos desarrolladores en el proyecto.

  • Rendimiento: Los alias no afectan al rendimiento en tiempo de ejecución, ya que se resuelven durante la compilación.

  • Depuración: En algunos casos, los mensajes de error pueden referirse al nombre original en lugar del alias, lo que puede causar confusión durante la depuración.

import { complexFunction as simpleFunction } from './module';

// Si hay un error, el stack trace podría mostrar 'complexFunction' en lugar de 'simpleFunction'
simpleFunction(); // Error

Los import aliases son una herramienta valiosa en el arsenal de TypeScript que, cuando se utilizan adecuadamente, pueden mejorar significativamente la legibilidad y mantenibilidad del código. Al proporcionar flexibilidad en la forma en que nombramos y organizamos nuestras importaciones, los alias nos ayudan a crear bases de código más limpias y expresivas.

CONSTRUYE TU CARRERA EN IA Y PROGRAMACIÓN SOFTWARE

Accede a +1000 lecciones y cursos con certificado. Mejora tu portfolio con certificados de superación para tu CV.

30 % DE DESCUENTO

Plan mensual

19.00 /mes

13.30 € /mes

Precio normal mensual: 19 €
63 % DE DESCUENTO

Plan anual

10.00 /mes

7.00 € /mes

Ahorras 144 € al año
Precio normal anual: 120 €
Aprende TypeScript online

Ejercicios de esta lección Exportación e importación de módulos

Evalúa tus conocimientos de esta lección Exportación e importación de módulos con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.

Funciones

TypeScript
Test

Reto composición de funciones

TypeScript
Código

Reto tipos especiales

TypeScript
Código

Reto tipos genéricos

TypeScript
Código

Módulos

TypeScript
Test

Polimorfismo

TypeScript
Código

Funciones TypeScript

TypeScript
Código

Interfaces

TypeScript
Puzzle

Funciones puras

TypeScript
Puzzle

Reto namespaces

TypeScript
Código

Funciones flecha

TypeScript
Puzzle

Polimorfismo

TypeScript
Test

Operadores

TypeScript
Test

Conversor de unidades

TypeScript
Proyecto

Funciones flecha

TypeScript
Test

Control de flujo

TypeScript
Código

Herencia

TypeScript
Puzzle

Clases

TypeScript
Puzzle

Proyecto validación de tipado

TypeScript
Proyecto

Clases y objetos

TypeScript
Código

Encapsulación

TypeScript
Test

Herencia

TypeScript
Test

Proyecto sistema de votación

TypeScript
Proyecto

Reto genéricos con clases

TypeScript
Código

Inmutabilidad

TypeScript
Puzzle

Interfaces

TypeScript
Test

Funciones de alto orden

TypeScript
Test

Reto map y filter

TypeScript
Código

Control de flujo

TypeScript
Test

Interfaces

TypeScript
Código

Reto funciones orden superior

TypeScript
Código

Herencia y clases abstractas

TypeScript
Código

Reto tipos mapped

TypeScript
Código

Herencia de clases

TypeScript
Código

Reto funciones puras

TypeScript
Código

Variables y constantes

TypeScript
Puzzle

Introducción a TypeScript

TypeScript
Test

Reto testing unitario

TypeScript
Código

Funciones de primera clase

TypeScript
Puzzle

Clases

TypeScript
Test

OOP y CRUD en TypeScript

TypeScript
Proyecto

Interfaces y su implementación

TypeScript
Código

Tipos genéricos

TypeScript
Test

Namespaces

TypeScript
Test

Proyecto calculadora gastos

TypeScript
Proyecto

Operadores y expresiones

TypeScript
Código

Proyecto generador de contraseñas

TypeScript
Proyecto

Reto unión e intersección

TypeScript
Código

Encapsulación

TypeScript
Puzzle

Tipos de unión e intersección

TypeScript
Test

Tipos de unión e intersección

TypeScript
Puzzle

Reto hola mundo en TS

TypeScript
Código

Variables y constantes

TypeScript
Código

Funciones puras

TypeScript
Test

Control de flujo

TypeScript
Código

Introducción a TypeScript

TypeScript
Código

Resolución de módulos

TypeScript
Test

Control de flujo

TypeScript
Puzzle

Reto tipos de utilidad

TypeScript
Código

Reto tipos literales y condicionales

TypeScript
Código

Reto exportar e importar

TypeScript
Código

Propiedades y métodos

TypeScript
Código

Tipos de utilidad

TypeScript
Test

Clases y objetos

TypeScript
Código

Tipos de datos, variables y constantes

TypeScript
Código

Proyecto Minigestor de tareas

TypeScript
Proyecto

Operadores

TypeScript
Puzzle

Funciones flecha y contexto

TypeScript
Código

Funciones

TypeScript
Puzzle

Reto type aliases

TypeScript
Código

Funciones de alto orden

TypeScript
Puzzle

Funciones y parámetros tipados

TypeScript
Código

Tipos literales

TypeScript
Puzzle

Reto enums

TypeScript
Código

Tipos de utilidad

TypeScript
Puzzle

Modificadores de acceso y encapsulación

TypeScript
Código

Polimorfismo

TypeScript
Puzzle

Tipos genéricos

TypeScript
Puzzle

Reto módulos

TypeScript
Código

Tipos literales

TypeScript
Test

Inmutabilidad

TypeScript
Test

Proyecto Generator de datos

TypeScript
Proyecto

Variables y constantes

TypeScript
Test

Funciones de primera clase

TypeScript
Test

Todas las lecciones de TypeScript

Accede a todas las lecciones de TypeScript y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Introducción A Typescript

TypeScript

Introducción Y Entorno

Instalación Y Configuración De Typescript

TypeScript

Introducción Y Entorno

Tipos De Datos, Variables Y Constantes

TypeScript

Sintaxis

Operadores Y Expresiones

TypeScript

Sintaxis

Control De Flujo

TypeScript

Sintaxis

Funciones Y Parámetros Tipados

TypeScript

Sintaxis

Funciones Flecha Y Contexto

TypeScript

Sintaxis

Enums

TypeScript

Sintaxis

Type Aliases Y Aserciones De Tipo

TypeScript

Sintaxis

Clases Y Objetos

TypeScript

Programación Orientada A Objetos

Interfaces Y Su Implementación

TypeScript

Programación Orientada A Objetos

Modificadores De Acceso Y Encapsulación

TypeScript

Programación Orientada A Objetos

Herencia Y Clases Abstractas

TypeScript

Programación Orientada A Objetos

Polimorfismo

TypeScript

Programación Orientada A Objetos

Decoradores Básicos

TypeScript

Programación Orientada A Objetos

Propiedades Y Métodos

TypeScript

Programación Orientada A Objetos

Inmutabilidad

TypeScript

Programación Funcional

Funciones Puras

TypeScript

Programación Funcional

Funciones De Primera Clase

TypeScript

Programación Funcional

Funciones De Alto Orden

TypeScript

Programación Funcional

Conceptos Básicos E Inmutabilidad

TypeScript

Programación Funcional

Funciones De Primera Clase Y Orden Superior

TypeScript

Programación Funcional

Composición De Funciones

TypeScript

Programación Funcional

Métodos Funcionales De Arrays (Map, Filter, Reduce)

TypeScript

Programación Funcional

Tipos Literales

TypeScript

Tipos Intermedios Y Avanzados

Tipos Genéricos

TypeScript

Tipos Intermedios Y Avanzados

Tipos De Unión E Intersección

TypeScript

Tipos Intermedios Y Avanzados

Tipos De Utilidad

TypeScript

Tipos Intermedios Y Avanzados

Unknown, Never Y Tipos Especiales

TypeScript

Tipos Intermedios Y Avanzados

Tipos Mapped

TypeScript

Tipos Intermedios Y Avanzados

Genéricos Con Clases E Interfaces

TypeScript

Tipos Intermedios Y Avanzados

Módulos

TypeScript

Namespaces Y Módulos

Namespaces

TypeScript

Namespaces Y Módulos

Resolución De Módulos

TypeScript

Namespaces Y Módulos

Exportación E Importación De Módulos

TypeScript

Namespaces Y Módulos

Introducción A Módulos

TypeScript

Namespaces Y Módulos

Testing Unitario En Typescript

TypeScript

Testing

Accede GRATIS a TypeScript y certifícate

En esta lección

Objetivos de aprendizaje de esta lección

  • Comprender la diferencia entre named exports y default exports en TypeScript.
  • Aprender a importar y exportar módulos usando ambas técnicas, incluyendo renombramientos.
  • Conocer la re-exportación para crear puntos de entrada unificados y mejorar la estructura del proyecto.
  • Entender cómo usar import aliases para evitar colisiones de nombres y mejorar la legibilidad.
  • Aplicar buenas prácticas para mantener un código modular, claro y mantenible en proyectos TypeScript.