TypeScript

TypeScript Decorator Patterns

Use experimental decorators for logging, validation, memoization, and dependency injection.

TypeScriptDecoratorsPatternsDI

Thumbnail for TypeScript Decorator Patterns

Overview

Use experimental decorators for logging, validation, memoization, and dependency injection.

Installation

bash
npm init -y
npm install typescript ts-node @types/node
npx tsc --init

Type Definitions

typescript
// Core types for TypeScript Decorator Patterns

type Result<T, E = Error> = 
  | { ok: true; value: T }
  | { ok: false; error: E };

interface Config {
  readonly name: string;
  readonly version: string;
  debug: boolean;
  features: Map<string, boolean>;
}

type DeepReadonly<T> = {
  readonly [P in keyof T]: T[P] extends object
    ? DeepReadonly<T[P]>
    : T[P];
};

type EventMap = {
  'item:created': { id: string; data: unknown };
  'item:updated': { id: string; changes: Partial<unknown> };
  'item:deleted': { id: string };
};

Implementation

typescript
class TypeSafeTypeScript {
  private registry = new Map<string, unknown>();
  private listeners = new Map<string, Set<Function>>();

  register<T>(key: string, value: T): this {
    this.registry.set(key, value);
    this.emit('item:created', { id: key, data: value });
    return this;
  }

  resolve<T>(key: string): Result<T> {
    const value = this.registry.get(key);
    if (value === undefined) {
      return { ok: false, error: new Error(\`Key "\${key}" not found\`) };
    }
    return { ok: true, value: value as T };
  }

  on<K extends keyof EventMap>(
    event: K,
    handler: (payload: EventMap[K]) => void
  ): () => void {
    if (!this.listeners.has(event)) {
      this.listeners.set(event, new Set());
    }
    this.listeners.get(event)!.add(handler);
    return () => this.listeners.get(event)?.delete(handler);
  }

  private emit<K extends keyof EventMap>(event: K, payload: EventMap[K]): void {
    this.listeners.get(event)?.forEach(fn => fn(payload));
  }
}

Usage

typescript
const manager = new TypeSafeTypeScript();

// Type-safe event listeners
const unsub = manager.on('item:created', (payload) => {
  console.log(\`Created: \${payload.id}\`);
});

// Register values
manager
  .register('config', { debug: true })
  .register('version', '1.0.0');

// Type-safe resolution
const result = manager.resolve<{ debug: boolean }>('config');
if (result.ok) {
  console.log('Debug mode:', result.value.debug);
}

unsub(); // Clean up listener

Testing

typescript
import { describe, it, expect } from 'vitest';

describe('TypeSafeTypeScript', () => {
  it('should register and resolve values', () => {
    const mgr = new TypeSafeTypeScript();
    mgr.register('key', 'value');
    const result = mgr.resolve<string>('key');
    expect(result.ok).toBe(true);
    if (result.ok) expect(result.value).toBe('value');
  });

  it('should return error for missing key', () => {
    const mgr = new TypeSafeTypeScript();
    const result = mgr.resolve('missing');
    expect(result.ok).toBe(false);
  });
});

Technologies

- TypeScript - Decorators - Patterns - DI

Related Projects

Comments (0)

Leave a Comment

No comments yet. Be the first to comment!