+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Part 141 of 355

πŸ“Ž Triple-Slash Directives: Reference Management

Master triple-slash directives to manage file dependencies, control compilation order, and create sophisticated build configurations πŸš€

πŸ’ŽAdvanced
24 min read

Prerequisites

  • Understanding of TypeScript compilation process and project structure πŸ“
  • Knowledge of module systems and file dependencies ⚑
  • Familiarity with build tools and configuration management πŸ’»

What you'll learn

  • Master all triple-slash directive types and their applications 🎯
  • Control compilation order and file dependencies effectively πŸ—οΈ
  • Create sophisticated build configurations and reference systems πŸ›
  • Build maintainable large-scale TypeScript projects ✨

🎯 Introduction

Welcome to the command center of TypeScript’s compilation orchestra! πŸ“Ž If TypeScript compilation were like conducting a symphony orchestra, then triple-slash directives are like the conductor’s precise gestures that tell each musician (file) exactly when to come in, which other musicians they need to listen to, and how they should coordinate to create beautiful, harmonious code together!

Triple-slash directives are special comments that provide instructions to the TypeScript compiler about file dependencies, compilation order, library references, and build configurations. They’re particularly powerful for managing complex projects, creating library definition files, and controlling the compilation process in sophisticated ways.

By the end of this tutorial, you’ll be a master conductor of TypeScript compilation, capable of orchestrating complex build processes and creating maintainable, well-organized TypeScript projects that compile efficiently and correctly every time. Let’s master the art of compilation coordination! 🌟

πŸ“š Understanding Triple-Slash Directives

πŸ€” What Are Triple-Slash Directives?

Triple-slash directives are single-line comments that start with /// and contain XML-like tags that provide instructions to the TypeScript compiler. They must appear at the top of files (before any code) and are used to declare dependencies between files, reference external libraries, and control compilation behavior.

// 🌟 Basic triple-slash directive examples

/// <reference path="./utilities.ts" />
/// <reference types="node" />
/// <reference lib="es2017" />

// Now the file can use utilities and Node.js types
import { formatDate, validateEmail } from './utilities';
import * as fs from 'fs';

interface UserData {
  id: string;
  email: string;
  createdAt: Date;
  preferences: UserPreferences;
}

interface UserPreferences {
  theme: 'light' | 'dark';
  language: string;
  notifications: NotificationSettings;
}

interface NotificationSettings {
  email: boolean;
  push: boolean;
  frequency: 'immediate' | 'daily' | 'weekly';
}

class UserManager {
  private users: Map<string, UserData> = new Map();
  private dataFile: string = './users.json';
  
  constructor() {
    this.loadUsers();
  }
  
  // 🎯 Using referenced utilities
  createUser(email: string): UserData {
    if (!validateEmail(email)) {
      throw new Error('Invalid email format');
    }
    
    const userData: UserData = {
      id: this.generateId(),
      email,
      createdAt: new Date(),
      preferences: {
        theme: 'light',
        language: 'en',
        notifications: {
          email: true,
          push: false,
          frequency: 'daily'
        }
      }
    };
    
    this.users.set(userData.id, userData);
    this.saveUsers();
    
    return userData;
  }
  
  // πŸ” Using Node.js APIs (from types reference)
  private loadUsers(): void {
    try {
      if (fs.existsSync(this.dataFile)) {
        const data = fs.readFileSync(this.dataFile, 'utf8');
        const usersArray: UserData[] = JSON.parse(data);
        
        for (const user of usersArray) {
          this.users.set(user.id, user);
        }
      }
    } catch (error) {
      console.error('Failed to load users:', error);
    }
  }
  
  private saveUsers(): void {
    try {
      const usersArray = Array.from(this.users.values());
      const data = JSON.stringify(usersArray, null, 2);
      fs.writeFileSync(this.dataFile, data, 'utf8');
    } catch (error) {
      console.error('Failed to save users:', error);
    }
  }
  
  // ✨ Using ES2017 features (from lib reference)
  async processUsers(): Promise<void> {
    const userEntries = Object.entries(this.users);
    
    // Using ES2017 Object.entries and async/await
    for (const [id, user] of userEntries) {
      await this.processUserData(user);
    }
  }
  
  private async processUserData(user: UserData): Promise<void> {
    // Simulate async processing
    return new Promise(resolve => {
      setTimeout(() => {
        console.log(`Processed user: ${user.email} (${formatDate(user.createdAt)})`);
        resolve();
      }, 100);
    });
  }
  
  private generateId(): string {
    return Math.random().toString(36).substr(2, 9);
  }
  
  getUserById(id: string): UserData | undefined {
    return this.users.get(id);
  }
  
  getAllUsers(): UserData[] {
    return Array.from(this.users.values());
  }
  
  updateUser(id: string, updates: Partial<UserData>): boolean {
    const user = this.users.get(id);
    if (!user) return false;
    
    const updatedUser = { ...user, ...updates };
    this.users.set(id, updatedUser);
    this.saveUsers();
    
    return true;
  }
  
  deleteUser(id: string): boolean {
    const deleted = this.users.delete(id);
    if (deleted) {
      this.saveUsers();
    }
    return deleted;
  }
}

// πŸš€ Global declarations using referenced types
declare global {
  namespace NodeJS {
    interface Global {
      userManager: UserManager;
    }
  }
}

// Initialize global user manager
if (typeof global !== 'undefined') {
  global.userManager = new UserManager();
}

export { UserManager, UserData, UserPreferences, NotificationSettings };

πŸ—οΈ Advanced Triple-Slash Directive Patterns

// πŸ”§ Complex reference management for large projects

/// <reference path="./types/global.d.ts" />
/// <reference path="./types/api.d.ts" />
/// <reference path="./types/database.d.ts" />
/// <reference types="node" />
/// <reference types="express" />
/// <reference lib="es2020" />
/// <reference lib="dom" />

// File: server/application.ts

import express from 'express';
import { DatabaseConnection } from './database/connection';
import { ApiRouter } from './api/router';
import { MiddlewareManager } from './middleware/manager';
import { ConfigurationManager } from './config/manager';

interface ApplicationConfig {
  port: number;
  host: string;
  environment: 'development' | 'staging' | 'production';
  database: DatabaseConfig;
  api: ApiConfig;
  middleware: MiddlewareConfig;
  logging: LoggingConfig;
}

interface DatabaseConfig {
  type: 'postgres' | 'mysql' | 'mongodb';
  host: string;
  port: number;
  database: string;
  username: string;
  password: string;
  pool: {
    min: number;
    max: number;
    idle: number;
  };
}

interface ApiConfig {
  version: string;
  prefix: string;
  rateLimit: {
    windowMs: number;
    max: number;
  };
  cors: {
    origin: string | string[];
    credentials: boolean;
  };
}

interface MiddlewareConfig {
  compression: boolean;
  helmet: boolean;
  morgan: boolean;
  bodyParser: {
    json: { limit: string };
    urlencoded: { limit: string; extended: boolean };
  };
}

interface LoggingConfig {
  level: 'debug' | 'info' | 'warn' | 'error';
  format: 'json' | 'combined' | 'common';
  file: {
    enabled: boolean;
    path: string;
    maxSize: string;
    maxFiles: number;
  };
}

class Application {
  private app: express.Application;
  private server?: import('http').Server;
  private database: DatabaseConnection;
  private config: ApplicationConfig;
  private middlewareManager: MiddlewareManager;
  private apiRouter: ApiRouter;
  
  constructor(config: ApplicationConfig) {
    this.config = config;
    this.app = express();
    this.database = new DatabaseConnection(config.database);
    this.middlewareManager = new MiddlewareManager(config.middleware);
    this.apiRouter = new ApiRouter(config.api);
    
    this.initialize();
  }
  
  // πŸ”§ Initialize application components
  private async initialize(): Promise<void> {
    console.log('πŸš€ Initializing application...');
    
    // Setup middleware
    await this.middlewareManager.setup(this.app);
    
    // Setup database connection
    await this.database.connect();
    
    // Setup API routes
    this.apiRouter.setup(this.app);
    
    // Setup error handling
    this.setupErrorHandling();
    
    console.log('βœ… Application initialized successfully');
  }
  
  // 🌐 Start the server
  async start(): Promise<void> {
    try {
      await this.initialize();
      
      this.server = this.app.listen(this.config.port, this.config.host, () => {
        console.log(`🌟 Server running on ${this.config.host}:${this.config.port}`);
        console.log(`πŸ“– Environment: ${this.config.environment}`);
        console.log(`πŸ”— API: http://${this.config.host}:${this.config.port}${this.config.api.prefix}`);
      });
      
      // Setup graceful shutdown
      this.setupGracefulShutdown();
      
    } catch (error) {
      console.error('❌ Failed to start server:', error);
      process.exit(1);
    }
  }
  
  // πŸ›‘ Stop the server
  async stop(): Promise<void> {
    console.log('πŸ›‘ Stopping application...');
    
    if (this.server) {
      await new Promise<void>((resolve) => {
        this.server!.close(() => {
          console.log('βœ… HTTP server closed');
          resolve();
        });
      });
    }
    
    await this.database.disconnect();
    console.log('βœ… Application stopped gracefully');
  }
  
  // 🚨 Setup error handling
  private setupErrorHandling(): void {
    // Handle 404 errors
    this.app.use('*', (req, res) => {
      res.status(404).json({
        error: 'Not Found',
        message: `Route ${req.originalUrl} not found`,
        statusCode: 404
      });
    });
    
    // Global error handler
    this.app.use((err: Error, req: express.Request, res: express.Response, next: express.NextFunction) => {
      console.error('🚨 Unhandled error:', err);
      
      const isDevelopment = this.config.environment === 'development';
      
      res.status(500).json({
        error: 'Internal Server Error',
        message: isDevelopment ? err.message : 'Something went wrong',
        statusCode: 500,
        ...(isDevelopment && { stack: err.stack })
      });
    });
  }
  
  // πŸ”„ Setup graceful shutdown
  private setupGracefulShutdown(): void {
    const shutdown = async (signal: string) => {
      console.log(`\nπŸ“‘ Received ${signal}, shutting down gracefully...`);
      await this.stop();
      process.exit(0);
    };
    
    process.on('SIGTERM', () => shutdown('SIGTERM'));
    process.on('SIGINT', () => shutdown('SIGINT'));
    
    // Handle uncaught exceptions
    process.on('uncaughtException', (error) => {
      console.error('πŸ’₯ Uncaught Exception:', error);
      shutdown('uncaughtException');
    });
    
    // Handle unhandled rejections
    process.on('unhandledRejection', (reason) => {
      console.error('πŸ’₯ Unhandled Rejection:', reason);
      shutdown('unhandledRejection');
    });
  }
  
  // πŸ“Š Get application health status
  getHealthStatus(): HealthStatus {
    return {
      status: 'healthy',
      timestamp: new Date().toISOString(),
      uptime: process.uptime(),
      version: process.env.npm_package_version || '1.0.0',
      environment: this.config.environment,
      database: this.database.isConnected() ? 'connected' : 'disconnected',
      memory: process.memoryUsage(),
      cpu: process.cpuUsage()
    };
  }
  
  // πŸ”§ Get Express app instance (for testing)
  getApp(): express.Application {
    return this.app;
  }
}

interface HealthStatus {
  status: 'healthy' | 'unhealthy';
  timestamp: string;
  uptime: number;
  version: string;
  environment: string;
  database: 'connected' | 'disconnected';
  memory: NodeJS.MemoryUsage;
  cpu: NodeJS.CpuUsage;
}

// 🎯 Library-specific directives for different environments
/// <reference path="./environments/development.d.ts" />
/// <reference path="./environments/production.d.ts" />

// Conditional compilation based on environment
declare const __DEVELOPMENT__: boolean;
declare const __PRODUCTION__: boolean;

// Development-only features
if (__DEVELOPMENT__) {
  // Additional logging and debugging tools
  interface DevelopmentTools {
    debugger: DebuggerInterface;
    profiler: ProfilerInterface;
    hotReload: HotReloadInterface;
  }
  
  interface DebuggerInterface {
    breakpoint(label?: string): void;
    trace(message: string, data?: any): void;
    inspect(object: any): void;
  }
  
  interface ProfilerInterface {
    start(label: string): void;
    end(label: string): number;
    memory(): NodeJS.MemoryUsage;
  }
  
  interface HotReloadInterface {
    watch(files: string[]): void;
    reload(): void;
    isEnabled(): boolean;
  }
}

// Production-only optimizations
if (__PRODUCTION__) {
  interface ProductionOptimizations {
    monitoring: MonitoringInterface;
    analytics: AnalyticsInterface;
    security: SecurityInterface;
  }
  
  interface MonitoringInterface {
    reportError(error: Error, context?: any): void;
    reportMetric(name: string, value: number): void;
    reportEvent(event: string, data?: any): void;
  }
  
  interface AnalyticsInterface {
    track(event: string, properties?: Record<string, any>): void;
    identify(userId: string, traits?: Record<string, any>): void;
    page(name: string, properties?: Record<string, any>): void;
  }
  
  interface SecurityInterface {
    validateRequest(req: express.Request): boolean;
    sanitizeInput(input: any): any;
    checkRateLimit(ip: string): boolean;
  }
}

export { Application, ApplicationConfig, HealthStatus };

// πŸ”— Example of complex dependency chain
/// <reference path="./base/foundation.ts" />
/// <reference path="./base/utilities.ts" />
/// <reference path="./core/interfaces.ts" />
/// <reference path="./core/abstractions.ts" />
/// <reference path="./services/implementations.ts" />

// File demonstrating layered architecture through references
namespace Architecture {
  
  // πŸ—οΈ Foundation layer (referenced first)
  export namespace Foundation {
    export interface Logger {
      debug(message: string): void;
      info(message: string): void;
      warn(message: string): void;
      error(message: string): void;
    }
    
    export interface EventEmitter {
      on(event: string, listener: Function): void;
      emit(event: string, ...args: any[]): void;
      off(event: string, listener: Function): void;
    }
    
    export interface Disposable {
      dispose(): void | Promise<void>;
    }
  }
  
  // πŸ”§ Core layer (depends on foundation)
  export namespace Core {
    export interface Service extends Foundation.Disposable {
      name: string;
      version: string;
      start(): Promise<void>;
      stop(): Promise<void>;
      isRunning(): boolean;
    }
    
    export interface Repository<T, K = string> {
      find(id: K): Promise<T | null>;
      findAll(): Promise<T[]>;
      save(entity: T): Promise<T>;
      delete(id: K): Promise<boolean>;
    }
    
    export interface UseCase<TRequest, TResponse> {
      execute(request: TRequest): Promise<TResponse>;
    }
  }
  
  // 🎯 Application layer (depends on core)
  export namespace Application {
    export interface Controller {
      handle(request: any, response: any): Promise<void>;
    }
    
    export interface Middleware {
      process(context: any, next: Function): Promise<void>;
    }
    
    export interface Router {
      route(path: string, controller: Controller): void;
      use(middleware: Middleware): void;
    }
  }
  
  // 🌐 Infrastructure layer (implements interfaces)
  export namespace Infrastructure {
    export class DatabaseRepository<T, K = string> implements Core.Repository<T, K> {
      constructor(private connection: any) {}
      
      async find(id: K): Promise<T | null> {
        // Database implementation
        return null;
      }
      
      async findAll(): Promise<T[]> {
        // Database implementation
        return [];
      }
      
      async save(entity: T): Promise<T> {
        // Database implementation
        return entity;
      }
      
      async delete(id: K): Promise<boolean> {
        // Database implementation
        return true;
      }
    }
    
    export class HttpController implements Application.Controller {
      async handle(request: any, response: any): Promise<void> {
        // HTTP handling implementation
      }
    }
    
    export class ExpressRouter implements Application.Router {
      private app: express.Application;
      
      constructor(app: express.Application) {
        this.app = app;
      }
      
      route(path: string, controller: Application.Controller): void {
        this.app.all(path, (req, res) => controller.handle(req, res));
      }
      
      use(middleware: Application.Middleware): void {
        this.app.use((req, res, next) => middleware.process({ req, res }, next));
      }
    }
  }
}

πŸ› οΈ Building a Triple-Slash Directive Management System

Let’s create a comprehensive system for managing triple-slash directives in large projects:

// πŸ—οΈ Triple-Slash Directive Management and Analysis System

/// <reference types="node" />
/// <reference lib="es2020" />

namespace DirectiveManagement {
  
  // πŸ“‹ Core interfaces for directive management
  export interface DirectiveRegistry {
    files: Map<string, FileDirectives>;
    dependencies: Map<string, DependencyInfo>;
    libraries: Map<string, LibraryInfo>;
    buildOrder: string[];
    conflicts: DirectiveConflict[];
    metadata: RegistryMetadata;
  }
  
  export interface FileDirectives {
    filePath: string;
    directives: ParsedDirective[];
    dependencies: string[];
    dependents: string[];
    lastModified: Date;
    compilationOrder: number;
    errors: DirectiveError[];
    warnings: DirectiveWarning[];
  }
  
  export interface ParsedDirective {
    type: DirectiveType;
    value: string;
    line: number;
    column: number;
    raw: string;
    parsed: DirectiveContent;
  }
  
  export type DirectiveType = 'path' | 'types' | 'lib' | 'amd-module' | 'amd-dependency' | 'no-default-lib';
  
  export interface DirectiveContent {
    path?: string;
    types?: string;
    lib?: string;
    name?: string;
    dependency?: string;
    noDefaultLib?: boolean;
  }
  
  export interface DependencyInfo {
    source: string;
    target: string;
    type: DirectiveType;
    resolved: boolean;
    circular: boolean;
    depth: number;
  }
  
  export interface LibraryInfo {
    name: string;
    version?: string;
    path: string;
    files: string[];
    dependencies: string[];
    usage: LibraryUsage[];
  }
  
  export interface LibraryUsage {
    file: string;
    directive: ParsedDirective;
    required: boolean;
  }
  
  export interface DirectiveConflict {
    type: ConflictType;
    files: string[];
    directives: ParsedDirective[];
    severity: 'error' | 'warning' | 'info';
    description: string;
    resolution?: ConflictResolution;
  }
  
  export type ConflictType = 
    | 'circular_dependency' 
    | 'missing_reference' 
    | 'duplicate_library' 
    | 'version_mismatch' 
    | 'invalid_path';
  
  export interface ConflictResolution {
    strategy: 'remove' | 'update' | 'reorder' | 'ignore';
    details: string;
    automatic: boolean;
  }
  
  export interface DirectiveError {
    type: 'syntax' | 'missing_file' | 'circular_reference' | 'invalid_library';
    message: string;
    directive: ParsedDirective;
    severity: 'error' | 'warning';
  }
  
  export interface DirectiveWarning {
    type: 'unused_reference' | 'deprecated_library' | 'performance' | 'best_practice';
    message: string;
    directive?: ParsedDirective;
    suggestion?: string;
  }
  
  export interface RegistryMetadata {
    totalFiles: number;
    totalDirectives: number;
    lastScanned: Date;
    version: string;
    projectRoot: string;
  }
  
  // πŸ”§ Directive Parser and Analyzer
  export class DirectiveAnalyzer {
    private registry: DirectiveRegistry;
    private fileSystem: FileSystemInterface;
    private validator: DirectiveValidator;
    private resolver: DependencyResolver;
    
    constructor(projectRoot: string) {
      this.registry = this.initializeRegistry(projectRoot);
      this.fileSystem = new FileSystemAdapter();
      this.validator = new DirectiveValidator();
      this.resolver = new DependencyResolver();
    }
    
    // πŸ“ Scan project for directives
    async scanProject(rootPath: string = this.registry.metadata.projectRoot): Promise<ScanResult> {
      console.log(`πŸ“ Scanning project for triple-slash directives: ${rootPath}`);
      
      try {
        const typeScriptFiles = await this.findTypeScriptFiles(rootPath);
        const results: FileAnalysisResult[] = [];
        
        for (const filePath of typeScriptFiles) {
          const result = await this.analyzeFile(filePath);
          results.push(result);
          
          if (result.success) {
            this.registry.files.set(filePath, result.directives!);
          }
        }
        
        // Build dependency graph
        this.buildDependencyGraph();
        
        // Detect conflicts
        const conflicts = this.detectConflicts();
        this.registry.conflicts = conflicts;
        
        // Calculate compilation order
        const buildOrder = this.calculateBuildOrder();
        this.registry.buildOrder = buildOrder;
        
        // Update metadata
        this.updateMetadata();
        
        return {
          success: true,
          filesScanned: typeScriptFiles.length,
          directivesFound: this.getTotalDirectives(),
          conflicts: conflicts.length,
          buildOrder,
          results
        };
        
      } catch (error) {
        return {
          success: false,
          error: `Scan failed: ${error.message}`,
          filesScanned: 0,
          directivesFound: 0,
          conflicts: 0,
          buildOrder: [],
          results: []
        };
      }
    }
    
    // πŸ” Analyze single file for directives
    async analyzeFile(filePath: string): Promise<FileAnalysisResult> {
      console.log(`πŸ” Analyzing file: ${filePath}`);
      
      try {
        const content = await this.fileSystem.readFile(filePath);
        const lines = content.split('\n');
        
        const directives: ParsedDirective[] = [];
        const errors: DirectiveError[] = [];
        const warnings: DirectiveWarning[] = [];
        
        // Parse directives (only from the top of the file)
        for (let i = 0; i < lines.length; i++) {
          const line = lines[i].trim();
          
          // Stop parsing if we hit non-directive content
          if (line && !line.startsWith('///') && !line.startsWith('//') && !line.startsWith('/*')) {
            break;
          }
          
          if (line.startsWith('///')) {
            const parseResult = this.parseDirective(line, i + 1, 0);
            
            if (parseResult.success) {
              directives.push(parseResult.directive!);
            } else {
              errors.push({
                type: 'syntax',
                message: parseResult.error!,
                directive: parseResult.directive!,
                severity: 'error'
              });
            }
          }
        }
        
        // Validate directives
        const validationResult = this.validator.validate(directives, filePath);
        errors.push(...validationResult.errors);
        warnings.push(...validationResult.warnings);
        
        // Extract dependencies
        const dependencies = this.extractDependencies(directives);
        
        const fileDirectives: FileDirectives = {
          filePath,
          directives,
          dependencies,
          dependents: [], // Will be populated during dependency graph building
          lastModified: await this.fileSystem.getLastModified(filePath),
          compilationOrder: -1, // Will be set during build order calculation
          errors,
          warnings
        };
        
        return {
          success: true,
          filePath,
          directives: fileDirectives
        };
        
      } catch (error) {
        return {
          success: false,
          filePath,
          error: `Analysis failed: ${error.message}`
        };
      }
    }
    
    // 🧩 Parse individual directive
    private parseDirective(line: string, lineNumber: number, column: number): DirectiveParseResult {
      const trimmed = line.substring(3).trim(); // Remove '///'
      
      // Match different directive patterns
      const patterns = {
        path: /^<reference\s+path\s*=\s*["']([^"']+)["']\s*\/?>$/,
        types: /^<reference\s+types\s*=\s*["']([^"']+)["']\s*\/?>$/,
        lib: /^<reference\s+lib\s*=\s*["']([^"']+)["']\s*\/?>$/,
        amdModule: /^<amd-module\s+name\s*=\s*["']([^"']+)["']\s*\/?>$/,
        amdDependency: /^<amd-dependency\s+path\s*=\s*["']([^"']+)["']\s*(?:name\s*=\s*["']([^"']+)["'])?\s*\/?>$/,
        noDefaultLib: /^<reference\s+no-default-lib\s*=\s*["']true["']\s*\/?>$/
      };
      
      for (const [type, pattern] of Object.entries(patterns)) {
        const match = trimmed.match(pattern);
        if (match) {
          const directive: ParsedDirective = {
            type: type as DirectiveType,
            value: match[1] || 'true',
            line: lineNumber,
            column,
            raw: line,
            parsed: this.createDirectiveContent(type as DirectiveType, match)
          };
          
          return { success: true, directive };
        }
      }
      
      // If no pattern matches, it's an invalid directive
      const invalidDirective: ParsedDirective = {
        type: 'path', // Default type for error reporting
        value: trimmed,
        line: lineNumber,
        column,
        raw: line,
        parsed: {}
      };
      
      return {
        success: false,
        directive: invalidDirective,
        error: `Invalid triple-slash directive syntax: ${trimmed}`
      };
    }
    
    // πŸ”§ Create directive content object
    private createDirectiveContent(type: DirectiveType, match: RegExpMatchArray): DirectiveContent {
      switch (type) {
        case 'path':
          return { path: match[1] };
        case 'types':
          return { types: match[1] };
        case 'lib':
          return { lib: match[1] };
        case 'amd-module':
          return { name: match[1] };
        case 'amd-dependency':
          return { dependency: match[1], name: match[2] };
        case 'no-default-lib':
          return { noDefaultLib: true };
        default:
          return {};
      }
    }
    
    // πŸ”— Extract file dependencies from directives
    private extractDependencies(directives: ParsedDirective[]): string[] {
      const dependencies: string[] = [];
      
      for (const directive of directives) {
        if (directive.type === 'path' && directive.parsed.path) {
          dependencies.push(directive.parsed.path);
        }
      }
      
      return dependencies;
    }
    
    // πŸ“Š Build dependency graph
    private buildDependencyGraph(): void {
      console.log('πŸ“Š Building dependency graph');
      
      this.registry.dependencies.clear();
      
      for (const [filePath, fileDirectives] of this.registry.files) {
        for (const dependency of fileDirectives.dependencies) {
          const resolvedPath = this.resolver.resolvePath(dependency, filePath);
          
          const dependencyInfo: DependencyInfo = {
            source: filePath,
            target: resolvedPath,
            type: 'path',
            resolved: this.registry.files.has(resolvedPath),
            circular: false, // Will be calculated later
            depth: 0 // Will be calculated later
          };
          
          const key = `${filePath}->${resolvedPath}`;
          this.registry.dependencies.set(key, dependencyInfo);
          
          // Update dependents
          const targetFile = this.registry.files.get(resolvedPath);
          if (targetFile) {
            targetFile.dependents.push(filePath);
          }
        }
      }
      
      // Detect circular dependencies
      this.detectCircularDependencies();
    }
    
    // πŸ”„ Detect circular dependencies
    private detectCircularDependencies(): void {
      console.log('πŸ”„ Detecting circular dependencies');
      
      const visited = new Set<string>();
      const recursionStack = new Set<string>();
      
      const visit = (filePath: string, path: string[]): boolean => {
        if (recursionStack.has(filePath)) {
          // Found circular dependency
          const cycleStart = path.indexOf(filePath);
          const cycle = path.slice(cycleStart).concat(filePath);
          this.markCircularDependency(cycle);
          return true;
        }
        
        if (visited.has(filePath)) {
          return false;
        }
        
        visited.add(filePath);
        recursionStack.add(filePath);
        
        const fileDirectives = this.registry.files.get(filePath);
        if (fileDirectives) {
          for (const dependency of fileDirectives.dependencies) {
            const resolvedPath = this.resolver.resolvePath(dependency, filePath);
            if (visit(resolvedPath, [...path, filePath])) {
              return true;
            }
          }
        }
        
        recursionStack.delete(filePath);
        return false;
      };
      
      for (const filePath of this.registry.files.keys()) {
        if (!visited.has(filePath)) {
          visit(filePath, []);
        }
      }
    }
    
    // πŸ”΄ Mark circular dependency
    private markCircularDependency(cycle: string[]): void {
      for (let i = 0; i < cycle.length - 1; i++) {
        const source = cycle[i];
        const target = cycle[i + 1];
        const key = `${source}->${target}`;
        
        const dependency = this.registry.dependencies.get(key);
        if (dependency) {
          dependency.circular = true;
        }
      }
    }
    
    // ⚠️ Detect conflicts
    private detectConflicts(): DirectiveConflict[] {
      console.log('⚠️ Detecting directive conflicts');
      
      const conflicts: DirectiveConflict[] = [];
      
      // Check for circular dependencies
      for (const [, dependency] of this.registry.dependencies) {
        if (dependency.circular) {
          conflicts.push({
            type: 'circular_dependency',
            files: [dependency.source, dependency.target],
            directives: [],
            severity: 'error',
            description: `Circular dependency detected between ${dependency.source} and ${dependency.target}`,
            resolution: {
              strategy: 'reorder',
              details: 'Reorganize file structure to eliminate circular dependencies',
              automatic: false
            }
          });
        }
      }
      
      // Check for missing references
      for (const [, dependency] of this.registry.dependencies) {
        if (!dependency.resolved) {
          conflicts.push({
            type: 'missing_reference',
            files: [dependency.source],
            directives: [],
            severity: 'error',
            description: `Missing reference file: ${dependency.target}`,
            resolution: {
              strategy: 'remove',
              details: 'Remove invalid reference or create missing file',
              automatic: false
            }
          });
        }
      }
      
      // Check for duplicate library references
      const libraryRefs = new Map<string, string[]>();
      for (const [filePath, fileDirectives] of this.registry.files) {
        for (const directive of fileDirectives.directives) {
          if (directive.type === 'types' && directive.parsed.types) {
            const lib = directive.parsed.types;
            if (!libraryRefs.has(lib)) {
              libraryRefs.set(lib, []);
            }
            libraryRefs.get(lib)!.push(filePath);
          }
        }
      }
      
      for (const [lib, files] of libraryRefs) {
        if (files.length > 3) { // Threshold for "too many references"
          conflicts.push({
            type: 'duplicate_library',
            files,
            directives: [],
            severity: 'warning',
            description: `Library ${lib} referenced in ${files.length} files - consider centralizing`,
            resolution: {
              strategy: 'reorder',
              details: 'Create a central types file for library references',
              automatic: true
            }
          });
        }
      }
      
      return conflicts;
    }
    
    // πŸ“ˆ Calculate compilation build order
    private calculateBuildOrder(): string[] {
      console.log('πŸ“ˆ Calculating compilation build order');
      
      const visited = new Set<string>();
      const buildOrder: string[] = [];
      
      const visit = (filePath: string): void => {
        if (visited.has(filePath)) {
          return;
        }
        
        visited.add(filePath);
        
        const fileDirectives = this.registry.files.get(filePath);
        if (fileDirectives) {
          // Visit dependencies first
          for (const dependency of fileDirectives.dependencies) {
            const resolvedPath = this.resolver.resolvePath(dependency, filePath);
            if (this.registry.files.has(resolvedPath)) {
              visit(resolvedPath);
            }
          }
          
          // Add this file to build order
          buildOrder.push(filePath);
          fileDirectives.compilationOrder = buildOrder.length;
        }
      };
      
      // Visit all files
      for (const filePath of this.registry.files.keys()) {
        visit(filePath);
      }
      
      return buildOrder;
    }
    
    // πŸ”§ Generate optimized directives
    generateOptimizedDirectives(filePath: string): OptimizationResult {
      console.log(`πŸ”§ Generating optimized directives for: ${filePath}`);
      
      const fileDirectives = this.registry.files.get(filePath);
      if (!fileDirectives) {
        return {
          success: false,
          error: `File ${filePath} not found in registry`
        };
      }
      
      const optimizations: Optimization[] = [];
      const optimizedDirectives: ParsedDirective[] = [...fileDirectives.directives];
      
      // Remove unused references
      const usedReferences = this.findUsedReferences(filePath);
      const unusedDirectives = optimizedDirectives.filter(d => 
        d.type === 'path' && !usedReferences.includes(d.parsed.path!)
      );
      
      if (unusedDirectives.length > 0) {
        optimizations.push({
          type: 'remove_unused',
          description: `Remove ${unusedDirectives.length} unused references`,
          impact: 'positive',
          savings: { compilationTime: unusedDirectives.length * 0.1 }
        });
        
        // Remove unused directives
        unusedDirectives.forEach(directive => {
          const index = optimizedDirectives.indexOf(directive);
          if (index !== -1) {
            optimizedDirectives.splice(index, 1);
          }
        });
      }
      
      // Consolidate library references
      const libraryConsolidation = this.consolidateLibraryReferences(optimizedDirectives);
      if (libraryConsolidation.changes > 0) {
        optimizations.push({
          type: 'consolidate_libraries',
          description: `Consolidated ${libraryConsolidation.changes} library references`,
          impact: 'positive',
          savings: { fileSize: libraryConsolidation.changes * 50 }
        });
      }
      
      // Reorder for optimal compilation
      const reorderedDirectives = this.reorderDirectives(optimizedDirectives);
      if (this.directivesChanged(optimizedDirectives, reorderedDirectives)) {
        optimizations.push({
          type: 'reorder',
          description: 'Reordered directives for optimal compilation',
          impact: 'positive',
          savings: { compilationTime: 0.2 }
        });
      }
      
      const newContent = this.generateDirectiveContent(reorderedDirectives);
      
      return {
        success: true,
        originalDirectives: fileDirectives.directives,
        optimizedDirectives: reorderedDirectives,
        optimizations,
        newContent,
        savings: this.calculateTotalSavings(optimizations)
      };
    }
    
    // πŸ“Š Generate comprehensive report
    generateReport(): DirectiveReport {
      console.log('πŸ“Š Generating comprehensive directive report');
      
      const files = Array.from(this.registry.files.values());
      const totalDirectives = this.getTotalDirectives();
      
      return {
        summary: {
          totalFiles: files.length,
          totalDirectives,
          totalConflicts: this.registry.conflicts.length,
          compilationOrder: this.registry.buildOrder.length,
          lastScanned: this.registry.metadata.lastScanned
        },
        fileBreakdown: files.map(f => ({
          path: f.filePath,
          directiveCount: f.directives.length,
          dependencyCount: f.dependencies.length,
          dependentCount: f.dependents.length,
          hasErrors: f.errors.length > 0,
          hasWarnings: f.warnings.length > 0,
          compilationOrder: f.compilationOrder
        })),
        conflicts: this.registry.conflicts,
        libraries: this.analyzeLibraryUsage(),
        dependencyGraph: this.buildDependencyGraphReport(),
        optimizationOpportunities: this.findOptimizationOpportunities(),
        recommendations: this.generateRecommendations(),
        generatedAt: new Date()
      };
    }
    
    // πŸ”§ Helper methods
    private initializeRegistry(projectRoot: string): DirectiveRegistry {
      return {
        files: new Map(),
        dependencies: new Map(),
        libraries: new Map(),
        buildOrder: [],
        conflicts: [],
        metadata: {
          totalFiles: 0,
          totalDirectives: 0,
          lastScanned: new Date(),
          version: '1.0.0',
          projectRoot
        }
      };
    }
    
    private async findTypeScriptFiles(rootPath: string): Promise<string[]> {
      return this.fileSystem.findFiles(rootPath, /\.tsx?$/);
    }
    
    private getTotalDirectives(): number {
      return Array.from(this.registry.files.values())
        .reduce((sum, file) => sum + file.directives.length, 0);
    }
    
    private updateMetadata(): void {
      this.registry.metadata.totalFiles = this.registry.files.size;
      this.registry.metadata.totalDirectives = this.getTotalDirectives();
      this.registry.metadata.lastScanned = new Date();
    }
    
    private findUsedReferences(filePath: string): string[] {
      // Implementation would analyze actual usage in the file
      return [];
    }
    
    private consolidateLibraryReferences(directives: ParsedDirective[]): { changes: number } {
      // Implementation would consolidate duplicate library references
      return { changes: 0 };
    }
    
    private reorderDirectives(directives: ParsedDirective[]): ParsedDirective[] {
      // Implementation would reorder directives optimally
      return [...directives];
    }
    
    private directivesChanged(original: ParsedDirective[], optimized: ParsedDirective[]): boolean {
      return original.length !== optimized.length ||
             original.some((d, i) => d.raw !== optimized[i]?.raw);
    }
    
    private generateDirectiveContent(directives: ParsedDirective[]): string {
      return directives.map(d => d.raw).join('\n');
    }
    
    private calculateTotalSavings(optimizations: Optimization[]): OptimizationSavings {
      return optimizations.reduce((total, opt) => ({
        compilationTime: (total.compilationTime || 0) + (opt.savings?.compilationTime || 0),
        fileSize: (total.fileSize || 0) + (opt.savings?.fileSize || 0)
      }), {});
    }
    
    private analyzeLibraryUsage(): LibraryUsageAnalysis[] {
      const usage: LibraryUsageAnalysis[] = [];
      const libraryMap = new Map<string, string[]>();
      
      for (const [filePath, fileDirectives] of this.registry.files) {
        for (const directive of fileDirectives.directives) {
          if (directive.type === 'types' && directive.parsed.types) {
            const lib = directive.parsed.types;
            if (!libraryMap.has(lib)) {
              libraryMap.set(lib, []);
            }
            libraryMap.get(lib)!.push(filePath);
          }
        }
      }
      
      for (const [library, files] of libraryMap) {
        usage.push({
          library,
          usageCount: files.length,
          files,
          recommended: files.length > 1
        });
      }
      
      return usage;
    }
    
    private buildDependencyGraphReport(): DependencyGraphReport {
      return {
        totalDependencies: this.registry.dependencies.size,
        circularDependencies: Array.from(this.registry.dependencies.values())
          .filter(d => d.circular).length,
        maxDepth: Math.max(...Array.from(this.registry.dependencies.values())
          .map(d => d.depth), 0),
        mostConnectedFiles: this.findMostConnectedFiles()
      };
    }
    
    private findMostConnectedFiles(): Array<{ file: string; connections: number }> {
      const connectionCounts = new Map<string, number>();
      
      for (const [filePath, fileDirectives] of this.registry.files) {
        const connections = fileDirectives.dependencies.length + fileDirectives.dependents.length;
        connectionCounts.set(filePath, connections);
      }
      
      return Array.from(connectionCounts.entries())
        .map(([file, connections]) => ({ file, connections }))
        .sort((a, b) => b.connections - a.connections)
        .slice(0, 10);
    }
    
    private findOptimizationOpportunities(): OptimizationOpportunity[] {
      const opportunities: OptimizationOpportunity[] = [];
      
      // Look for files with many dependencies
      for (const [filePath, fileDirectives] of this.registry.files) {
        if (fileDirectives.dependencies.length > 5) {
          opportunities.push({
            type: 'reduce_dependencies',
            file: filePath,
            description: `File has ${fileDirectives.dependencies.length} dependencies - consider refactoring`,
            priority: 'medium',
            estimatedImpact: 'moderate'
          });
        }
      }
      
      // Look for circular dependencies
      for (const conflict of this.registry.conflicts) {
        if (conflict.type === 'circular_dependency') {
          opportunities.push({
            type: 'eliminate_circular',
            file: conflict.files[0],
            description: conflict.description,
            priority: 'high',
            estimatedImpact: 'high'
          });
        }
      }
      
      return opportunities;
    }
    
    private generateRecommendations(): string[] {
      const recommendations: string[] = [];
      
      if (this.registry.conflicts.length > 0) {
        recommendations.push('Resolve directive conflicts to improve compilation reliability');
      }
      
      if (this.getTotalDirectives() > 100) {
        recommendations.push('Consider using a module bundler to reduce directive complexity');
      }
      
      const avgDirectivesPerFile = this.getTotalDirectives() / this.registry.files.size;
      if (avgDirectivesPerFile > 3) {
        recommendations.push('Review file structure - high average directives per file');
      }
      
      return recommendations;
    }
  }
  
  // πŸ”§ Supporting classes and interfaces
  class DirectiveValidator {
    validate(directives: ParsedDirective[], filePath: string): ValidationResult {
      const errors: DirectiveError[] = [];
      const warnings: DirectiveWarning[] = [];
      
      // Check for duplicate references
      const seen = new Set<string>();
      for (const directive of directives) {
        const key = `${directive.type}:${directive.value}`;
        if (seen.has(key)) {
          warnings.push({
            type: 'best_practice',
            message: `Duplicate ${directive.type} reference: ${directive.value}`,
            directive,
            suggestion: 'Remove duplicate reference'
          });
        }
        seen.add(key);
      }
      
      return { errors, warnings };
    }
  }
  
  class DependencyResolver {
    resolvePath(relativePath: string, fromFile: string): string {
      // Implementation would resolve relative paths to absolute paths
      // This is a simplified version
      if (relativePath.startsWith('./') || relativePath.startsWith('../')) {
        // Resolve relative to the directory containing fromFile
        const path = require('path');
        const dir = path.dirname(fromFile);
        return path.resolve(dir, relativePath);
      }
      return relativePath;
    }
  }
  
  class FileSystemAdapter implements FileSystemInterface {
    async readFile(filePath: string): Promise<string> {
      const fs = require('fs').promises;
      return fs.readFile(filePath, 'utf8');
    }
    
    async getLastModified(filePath: string): Promise<Date> {
      const fs = require('fs').promises;
      const stats = await fs.stat(filePath);
      return stats.mtime;
    }
    
    async findFiles(rootPath: string, pattern: RegExp): Promise<string[]> {
      const fs = require('fs').promises;
      const path = require('path');
      
      const files: string[] = [];
      
      const scan = async (dir: string): Promise<void> => {
        const entries = await fs.readdir(dir, { withFileTypes: true });
        
        for (const entry of entries) {
          const fullPath = path.join(dir, entry.name);
          
          if (entry.isDirectory()) {
            await scan(fullPath);
          } else if (entry.isFile() && pattern.test(entry.name)) {
            files.push(fullPath);
          }
        }
      };
      
      await scan(rootPath);
      return files;
    }
  }
  
  // πŸ“Š Supporting interfaces
  interface FileSystemInterface {
    readFile(filePath: string): Promise<string>;
    getLastModified(filePath: string): Promise<Date>;
    findFiles(rootPath: string, pattern: RegExp): Promise<string[]>;
  }
  
  interface ScanResult {
    success: boolean;
    filesScanned: number;
    directivesFound: number;
    conflicts: number;
    buildOrder: string[];
    results: FileAnalysisResult[];
    error?: string;
  }
  
  interface FileAnalysisResult {
    success: boolean;
    filePath: string;
    directives?: FileDirectives;
    error?: string;
  }
  
  interface DirectiveParseResult {
    success: boolean;
    directive: ParsedDirective;
    error?: string;
  }
  
  interface ValidationResult {
    errors: DirectiveError[];
    warnings: DirectiveWarning[];
  }
  
  interface OptimizationResult {
    success: boolean;
    originalDirectives?: ParsedDirective[];
    optimizedDirectives?: ParsedDirective[];
    optimizations?: Optimization[];
    newContent?: string;
    savings?: OptimizationSavings;
    error?: string;
  }
  
  interface Optimization {
    type: 'remove_unused' | 'consolidate_libraries' | 'reorder' | 'merge_files';
    description: string;
    impact: 'positive' | 'neutral' | 'negative';
    savings?: OptimizationSavings;
  }
  
  interface OptimizationSavings {
    compilationTime?: number;
    fileSize?: number;
    dependencies?: number;
  }
  
  interface DirectiveReport {
    summary: ReportSummary;
    fileBreakdown: FileBreakdown[];
    conflicts: DirectiveConflict[];
    libraries: LibraryUsageAnalysis[];
    dependencyGraph: DependencyGraphReport;
    optimizationOpportunities: OptimizationOpportunity[];
    recommendations: string[];
    generatedAt: Date;
  }
  
  interface ReportSummary {
    totalFiles: number;
    totalDirectives: number;
    totalConflicts: number;
    compilationOrder: number;
    lastScanned: Date;
  }
  
  interface FileBreakdown {
    path: string;
    directiveCount: number;
    dependencyCount: number;
    dependentCount: number;
    hasErrors: boolean;
    hasWarnings: boolean;
    compilationOrder: number;
  }
  
  interface LibraryUsageAnalysis {
    library: string;
    usageCount: number;
    files: string[];
    recommended: boolean;
  }
  
  interface DependencyGraphReport {
    totalDependencies: number;
    circularDependencies: number;
    maxDepth: number;
    mostConnectedFiles: Array<{ file: string; connections: number }>;
  }
  
  interface OptimizationOpportunity {
    type: 'reduce_dependencies' | 'eliminate_circular' | 'consolidate_references' | 'remove_unused';
    file: string;
    description: string;
    priority: 'low' | 'medium' | 'high';
    estimatedImpact: 'low' | 'moderate' | 'high';
  }
}

// πŸš€ Usage examples with the management system
const analyzer = new DirectiveManagement.DirectiveAnalyzer('./src');

// Scan entire project
const scanResult = await analyzer.scanProject();
if (scanResult.success) {
  console.log(`Scanned ${scanResult.filesScanned} files`);
  console.log(`Found ${scanResult.directivesFound} directives`);
  console.log(`Detected ${scanResult.conflicts} conflicts`);
  console.log('Build order:', scanResult.buildOrder);
} else {
  console.error('Scan failed:', scanResult.error);
}

// Analyze specific file
const fileResult = await analyzer.analyzeFile('./src/main.ts');
if (fileResult.success) {
  console.log('File analysis:', fileResult.directives);
} else {
  console.error('File analysis failed:', fileResult.error);
}

// Generate optimizations
const optimization = analyzer.generateOptimizedDirectives('./src/main.ts');
if (optimization.success) {
  console.log('Optimizations:', optimization.optimizations);
  console.log('Savings:', optimization.savings);
} else {
  console.error('Optimization failed:', optimization.error);
}

// Generate comprehensive report
const report = analyzer.generateReport();
console.log('Directive analysis report:', report);

🎯 Conclusion

Congratulations! You’ve now mastered the sophisticated art of triple-slash directives in TypeScript! πŸŽ‰

Throughout this tutorial, you’ve learned how to:

  • Master all triple-slash directive types including path references, type references, library references, and AMD directives
  • Control compilation order and dependencies effectively to ensure proper build sequences
  • Create sophisticated management systems for tracking and optimizing directives in large projects
  • Handle complex scenarios including circular dependencies, library consolidation, and build optimization
  • Build maintainable architectures that scale effectively with project growth

Triple-slash directives are the unsung heroes of TypeScript compilation, providing precise control over how your files are processed and how dependencies are resolved. When used correctly, they enable you to create well-organized, efficiently compiled projects that maintain clear dependency relationships and optimal build performance.

Remember: triple-slash directives are about orchestration and control, not replacement of modern module systems. Use them judiciously to complement your module architecture, especially in scenarios involving declaration files, library integration, and complex build requirements. With the management system and optimization strategies you’ve learned, you can confidently use triple-slash directives to create maintainable, efficient TypeScript projects.

Keep practicing these patterns, and you’ll find that triple-slash directives become a powerful tool for fine-tuning your TypeScript build process and creating sophisticated, well-organized codebases! πŸš€

πŸ“š Additional Resources