Skip to main content
Modules allow you to split your code into separate files and share functionality between them. TypeScript fully supports ES6 module syntax with added type safety.

Importing from Other Files

Use the import statement to bring in values from other modules:
import { heroes, Owner, type Hero } from '../data/heroes.data';
This imports:
  • heroes - a value (likely an array)
  • Owner - a type or value
  • Hero - explicitly a type (using type keyword)
The type keyword in type Hero explicitly marks it as a type-only import, which can be removed during compilation for better tree-shaking.

Using Imported Values

Once imported, you can use the values in your functions:
const getHeroById = (id: number): Hero => {
    const hero = heroes.find((hero) => {
        return hero.id === id;
    });

    if (!hero) throw new Error(`No existe el heroe con id ${id}`);

    return hero;
};

Exporting Functions

Use the export keyword to make functions available to other modules:
export const getHeroesByOwner = (owner: Owner) => {
    const heroesByOwner = heroes.filter(
        hero => hero.owner === owner
    );

    return heroesByOwner;
};
You can export functions, constants, classes, and types. Just add export before the declaration.

Types of Exports

Named Exports

Export multiple items from a module:
// heroes.data.ts
export const heroes = [...];
export type Hero = { ... };
export type Owner = 'Marvel' | 'DC';
Import specific named exports:
import { heroes, Hero, Owner } from '../data/heroes.data';

Default Exports

Export a single main value:
// utils.ts
export default function calculateTotal(items) {
    return items.reduce((sum, item) => sum + item.price, 0);
}
Import without braces:
import calculateTotal from './utils';

Type-Only Imports

Import only types (not runtime values):
import type { Hero } from '../data/heroes.data';
// or
import { type Hero, type Owner } from '../data/heroes.data';
Type-only imports are removed completely during compilation. Don’t use import type for values you need at runtime.

Module Resolution

TypeScript resolves module paths:
// Relative paths
import { Hero } from '../data/heroes.data';
import { utils } from './utils';

// Node modules
import React from 'react';
import axios from 'axios';

Best Practices

Organize Exports

Group related exports in a single file:
// types.ts
export interface User { ... }
export interface Product { ... }
export type Status = 'active' | 'inactive';

Use Barrel Exports

Create an index.ts file to re-export from multiple modules:
// index.ts
export * from './heroes';
export * from './villains';
export { default as utils } from './utils';

Prefer Named Exports

Named exports are easier to refactor and support better IDE autocomplete:
// ✓ Preferred
export const getHeroById = () => { ... };

// ✗ Less flexible
export default getHeroById;
Use named exports for libraries and reusable code. Reserve default exports for React components or when there’s a single obvious export.

Common Patterns

Organizing by Feature

src/
  heroes/
    heroes.data.ts
    heroes.service.ts
    heroes.types.ts
    index.ts

Index Files for Clean Imports

// Instead of:
import { Hero } from './heroes/heroes.types';
import { getHeroes } from './heroes/heroes.service';

// Use:
import { Hero, getHeroes } from './heroes';

Build docs developers (and LLMs) love