Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save coltenkrauter/870b2654520a5366b072e4c460686efa to your computer and use it in GitHub Desktop.
Save coltenkrauter/870b2654520a5366b072e4c460686efa to your computer and use it in GitHub Desktop.
Organizing a TypeScript Project

Organizing a TypeScript Project

Table of Contents

  1. Introduction
  2. Directory Structure
  3. Main Application File
  4. Modules and Subdirectories
  5. Type Definitions
  6. Exporting and Importing
  7. Benefits of Using ES Modules (ESM)

1. Introduction

This guide provides a comprehensive overview of how to organize a TypeScript project for maintainability and scalability. It includes directory structures, file naming conventions, and best practices for exporting and importing modules.

2. Directory Structure

A well-organized directory structure helps maintain a clean and understandable codebase. Here is an example structure for a TypeScript project:

/src
  /components
    /header
      header.ts
      structures.ts
      index.ts
    /footer
      footer.ts
      structures.ts
      index.ts
    index.ts
  /utils
    date.ts
    generateId.ts
    index.ts
  app.ts
  structures.ts

3. Main Application File

The main application file, app.ts, serves as the entry point for your application. It typically contains the core logic to start your application.

55555typescript // app.ts

import { Header, HeaderConfig } from './components/header/index.js'; import { Footer, FooterConfig } from './components/footer/index.js'; import { formatDate, generateId, getCurrentYear } from './utils/index.js';

const headerConfig: HeaderConfig = { title: 'Welcome' }; const header = new Header(headerConfig); header.render();

const footerConfig: FooterConfig = { text: '© 2023 Company' }; const footer = new Footer(footerConfig); footer.render();

const userId = generateId(); console.log('Generated User ID:', userId);

const formattedDate = formatDate(new Date()); console.log('Formatted Date:', formattedDate);

const currentYear = getCurrentYear(); console.log('Current Year:', currentYear); 55555

4. Modules and Subdirectories

Each module or component lives in its own directory. Use an index.ts file in each directory to export the module's public API.

Header Component

/components/header
  header.ts
  structures.ts
  index.ts

55555typescript // components/header/header.ts

import { HeaderConfig } from './structures.js';

export class Header { private config: HeaderConfig;

constructor(config: HeaderConfig) { this.config = config; }

render() { console.log('Rendering header with config:', this.config); } } 55555

55555typescript // components/header/structures.ts

export interface HeaderConfig { title: string; subtitle?: string; } 55555

55555typescript // components/header/index.ts

export { Header } from './header.js'; export { HeaderConfig } from './structures.js'; 55555

Footer Component

/components/footer
  footer.ts
  structures.ts
  index.ts

55555typescript // components/footer/footer.ts

import { FooterConfig } from './structures.js';

export class Footer { private config: FooterConfig;

constructor(config: FooterConfig) { this.config = config; }

render() { console.log('Rendering footer with config:', this.config); } } 55555

55555typescript // components/footer/structures.ts

export interface FooterConfig { text: string; } 55555

55555typescript // components/footer/index.ts

export { Footer } from './footer.js'; export { FooterConfig } from './structures.js'; 55555

Utilities

/utils
  date.ts
  generateId.ts
  index.ts

55555typescript // utils/date.ts

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

export function getCurrentYear(): number { return new Date().getFullYear(); } 55555

55555typescript // utils/generateId.ts

export function generateId(): string { return Math.random().toString(36).substr(2, 9); } 55555

55555typescript // utils/index.ts

export { formatDate, getCurrentYear } from './date.js'; export { generateId } from './generateId.js'; 55555

5. Type Definitions

Place shared types in a structures.ts file within each directory. This keeps type definitions close to where they are used.

6. Exporting and Importing

Use index.ts files to re-export modules and types from each directory. When importing, be explicit about what you are importing to keep the code clear and maintainable.

Example of Exporting and Importing

55555typescript // components/index.ts

export { Header, HeaderConfig } from './header/index.js'; export { Footer, FooterConfig } from './footer/index.js'; 55555

55555typescript // app.ts

import { Header, HeaderConfig, Footer, FooterConfig } from './components/index.js'; import { formatDate, getCurrentYear, generateId } from './utils/index.js';

const headerConfig: HeaderConfig = { title: 'Welcome' }; const header = new Header(headerConfig); header.render();

const footerConfig: FooterConfig = { text: '© 2023 Company' }; const footer = new Footer(footerConfig); footer.render();

const userId = generateId(); console.log('Generated User ID:', userId);

const formattedDate = formatDate(new Date()); console.log('Formatted Date:', formattedDate);

const currentYear = getCurrentYear(); console.log('Current Year:', currentYear); 55555

7. Benefits of Using ES Modules (ESM)

ES Modules (ESM) and CommonJS are both module systems used in JavaScript, but ESM is the standardized module system defined by ECMAScript, while CommonJS is the older module system primarily used in Node.js.

Benefits of Using ES Modules:

  1. Standardization: ESM is the official standard for JavaScript modules, ensuring consistency across different environments and platforms.
  2. Tree Shaking: ESM supports tree shaking, allowing bundlers to remove unused code from the final bundle, which can lead to smaller and more efficient builds.
  3. Static Analysis: ESM enables better static analysis of imports and exports, improving tooling support, such as IDE features, linting, and code refactoring.
  4. Better Compatibility: As the web moves towards using ESM, using it in your projects ensures better compatibility with modern tools and libraries.

For more information on the differences and benefits, you can read Node.js documentation on ESM.


This Gist was created with the assistance of ChatGPT.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment