Refactoring von Legacy-Code in TypeScript: Schritt-für-Schritt-Anleitung

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten
```html

Einleitung: Warum die Refaktorisierung von Legacy-Code auf TypeScript notwendig ist

Die Arbeit mit vererbtem (Legacy-)Code ist eine der häufigsten und anspruchsvollsten Aufgaben für Entwickler. Oft ist solcher Code in reinem JavaScript ohne strenge Typisierung geschrieben, enthält verworrene Abhängigkeiten und es fehlt eine modulare Struktur. Der Wechsel zu TypeScript fügt nicht nur Typen hinzu – es ist eine grundlegende Verbesserung der Codequalität, die die Anzahl der Fehler reduziert, die Refaktorisierung vereinfacht und das Onboarding neuer Entwickler beschleunigt.

In diesem Artikel werden wir den schrittweisen Prozess der Refaktorisierung von Legacy-Code auf TypeScript durchgehen. Sie erfahren, wie Sie Typen sicher einführen, monolithische Funktionen aufteilen und Änderungen testen.



Schritt 1. Analyse und Vorbereitung des Legacy-Codes

Bevor Sie Code schreiben, müssen Sie die aktuelle Architektur verstehen. Ohne dies wird die Refaktorisierung zum Chaos.



Erstellen Sie eine Abhängigkeitskarte

Beginnen Sie mit der Analyse von Dateien und Modulen. Ermitteln Sie:

  • Welche Funktionen "rein" (pure) sind und welche Seiteneffekte haben.
  • Wo sich globale Variablen und Zustände befinden.
  • Welche Codeabschnitte dupliziert werden.


Schreiben Sie Tests für kritische Bereiche

Refaktorisierung ohne Tests ist russisches Roulette. Schreiben Sie zumindest Modultests für die Schlüsselfunktionen. Beispiel eines Tests in TypeScript:

// Ursprünglicher Legacy-Code (JavaScript)function calculatePrice(items) {    let total = 0;    for (let i = 0; i < items.length; i++) {        total += items[i].price * items[i].quantity;    }    return total;}

// Test in TypeScript (Jest)describe('calculatePrice', () => { it('should calculate total price correctly', () => { const items = [ { price: 10, quantity: 2 }, { price: 5, quantity: 3 } ]; expect(calculatePrice(items)).toBe(35); });});


Wenn die Tests bestanden werden, kann die Refaktorisierung beginnen.



Schritt 2. Schrittweise Einführung der strengen Typisierung

Versuchen Sie nicht, alles auf einmal mit Typen zu versehen. Verwenden Sie die "Bottom-up"-Strategie: Beginnen Sie mit den einfachsten und isoliertesten Funktionen.



Typisierung einfacher Funktionen

Fügen Sie Typen für Parameter und Rückgabewerte hinzu. Beispiel:

// Vorher (JavaScript)function greet(name) {    return "Hello, " + name;}

// Nachher (TypeScript)function greet(name: string): string { return `Hello, ${name}`;}


Arbeit mit Objekten und Interfaces

Erstellen Sie für komplexe Datenstrukturen Interfaces. Das macht den Code selbstdokumentierend:

// Interface für ein Bestellelement definiereninterface OrderItem {    id: number;    name: string;    price: number;    quantity: number;}

// Funktion mit typisiertem Parameterfunction getTotalPrice(items: OrderItem[]): number { return items.reduce((sum, item) => sum + item.price * item.quantity, 0);}


Verwenden Sie `any` nur als temporäre Lösung

Der Typ any ist der Feind der strengen Typisierung. Wenn Sie den genauen Typ nicht kennen, verwenden Sie unknown und prüfen Sie ihn zur Laufzeit:

function safeParse(data: unknown): string {    if (typeof data === 'string') {        return data.trim();    }    return '';}


Schritt 3. Aufteilung monolithischer Funktionen und Module

Legacy-Code enthält oft "göttliche Funktionen" (god functions), die alles auf einmal erledigen. Teilen Sie sie in kleine, wiederverwendbare Module auf.



Auslagerung reiner Logik

Beispiel: Eine Funktion, die eine E-Mail validiert und eine Anfrage sendet. Teilen wir sie auf:

// Vorher (monolithisch)function processUser(email) {    if (!email || !email.includes('@')) {        throw new Error('Invalid email');    }    // ... Anfrage senden    console.log('Sending request...');}

// Nachher (Trennung der Verantwortlichkeiten)function validateEmail(email: string): boolean { return email ```

Blogs

Buchempfehlungen