Funktionale Programmierung in TypeScript: Grundlagen und Beispiele

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

Funktionale Programmierung in TypeScript: Von der Theorie zur Praxis

Funktionale Programmierung (FP) ist ein Paradigma, das auf der Berechnung durch die Anwendung von Funktionen und der Vermeidung von Zustandsänderungen basiert. TypeScript, als streng typisierte Obermenge von JavaScript, bietet leistungsstarke Werkzeuge zur Umsetzung von FP. In diesem Artikel werden wir die wichtigsten Konzepte der funktionalen Programmierung in TypeScript mit praktischen Codebeispielen behandeln.



1. Reine Funktionen und Unveränderlichkeit (Immutability)

Reine Funktion ist eine Funktion, die:

  • Für dieselben Argumente immer dasselbe Ergebnis zurückgibt (Determinismus).
  • Keine Nebenwirkungen hat (keine externen Variablen ändert, keine I/O-Operationen durchführt).
// Reine Funktionconst add = (a: number, b: number): number => a + b;

// Unreine Funktion (Nebenwirkung — Änderung des externen Zustands)let counter = 0;const increment = (): number => ++counter;

Unveränderlichkeit (Immutability) bedeutet, dass Daten nicht geändert werden, sondern neue Kopien erstellt werden. In TypeScript können der Spread-Operator und Methoden ohne Mutationen verwendet werden:

interface User {  name: string;  age: number;}

// Mutation (schlecht)const updateAgeMutable = (user: User, newAge: number): void => { user.age = newAge;};

// Unveränderlicher Ansatz (gut)const updateAgeImmutable = (user: User, newAge: number): User => ({ ...user, age: newAge,});

Unveränderlichkeit vereinfacht das Debugging und Testen, da Daten immer vorhersagbar sind.



2. Funktionen höherer Ordnung und Closures

Funktionen höherer Ordnung sind Funktionen, die andere Funktionen als Argumente annehmen oder zurückgeben. Ein Beispiel ist die Methode Array.map:

const numbers: number[] = [1, 2, 3, 4];const doubled: number[] = numbers.map((x) => x * 2);console.log(doubled); // [2, 4, 6, 8]

Closure ist eine Funktion, die sich an Variablen aus dem äußeren Gültigkeitsbereich "erinnert", selbst nachdem die äußere Funktion ihre Ausführung beendet hat:

const createMultiplier = (factor: number): ((x: number) => number) => {  return (x: number) => x * factor;};

const double = createMultiplier(2);const triple = createMultiplier(3);

console.log(double(5)); // 10console.log(triple(5)); // 15

Closures werden häufig verwendet, um Funktionen mit partieller Anwendung von Argumenten (Currying) zu erstellen.



3. Funktionskomposition und Currying

Funktionskomposition ist die Kombination mehrerer Funktionen zu einer, bei der die Ausgabe einer Funktion die Eingabe für die nächste ist. In TypeScript kann man ein Hilfsmittel für die Komposition schreiben:

const compose = <T, R>(...fns: Array<(arg: T) => T>) => (arg: T): T =>   fns.reduceRight((acc, fn) => fn(acc), arg);

// Beispiel: Zeichenkette umwandelnconst toUpperCase = (s: string): string => s.toUpperCase();const exclaim = (s: string): string => `${s}!`;const shout = compose(toUpperCase, exclaim);

console.log(shout("hello")); // "HELLO!"

Currying ist die Umwandlung einer Funktion mit mehreren Argumenten in eine Folge von Funktionen mit jeweils einem Argument:

// Normale Funktionconst add = (a: number, b: number): number => a + b;

// Curry-Versionconst curriedAdd = (a: number) => (b: number): number => a + b;

const add5 = curriedAdd(5);console.log(add5(3)); // 8

Currying vereinfacht die Erstellung spezialisierter Funktionen und erhöht die Wiederverwendbarkeit von Code.



4. Monaden und Arbeiten mit Option/Maybe

Eine Monade ist ein Muster der funktionalen Programmierung, das einen Wert kapselt und eine Schnittstelle zu seiner Transformation bereitstellt. Eine der einfachsten Monaden ist Maybe (oder Option), die sicher mit n

Blogs

Buchempfehlungen