Kategorie Bild Software-Entwicklung
Zurück zur Übersicht

Warum Union Types die Generic-Debatte so schwierig machen

Warum die Kombination aus Union Types und Generics in PHP schnell teuer wird und wie ich in Projekten trotzdem typsicher bleibe.

Im Review sieht Repository<BlogPost|User|Event> erstmal sauber aus. Beim nächsten Refactoring hängen wir plötzlich in drei Sonderfällen gleichzeitig.

Genau diese Reibung sehe ich in PHP-Projekten immer wieder. Auf dem Papier wirkt die Kombination elegant, im Betrieb wird sie schnell zäh.

Ich bekomme dazu oft die Frage, warum genau diese Verbindung so viel Reibung erzeugt. Die Antwort ist technisch, aber im Projektalltag sehr greifbar.

Union Types sind sinnvoll, bis sie mit Generics kollidieren

Union Types wie User|Event nutze ich selbst gern. Sie machen an vielen Stellen APIs klarer, weil sie erlaubte Varianten explizit benennen.

Das Problem beginnt dort, wo ich diese Typen in generische Konstrukte hineinziehe. Ein Beispiel wie Repository<BlogPost|User|Event> wirkt zunächst elegant, erzeugt intern aber sehr viele zusätzliche Pfade für Typprüfung und Auflösung.

In einer dynamischen Laufzeit wie PHP wird das schnell teuer.

Warum die Komplexität so stark ansteigt

Ich denke bei dem Thema in Entscheidungspfaden. Jeder zusätzliche Typ in einer Union erzeugt weitere Varianten, die zur Laufzeit korrekt behandelt werden müssen.

Bei einfachen Typen ist das noch überschaubar. Bei generischen, verschachtelten oder vererbten Konstrukten wächst die Anzahl möglicher Kombinationen sehr schnell.

Das bedeutet in der Praxis:

  • mehr Arbeit für die Typprüfung,
  • mehr Sonderfälle in der Implementierung,
  • mehr Risiko für Performance-Einbrüche bei komplexen Hot Paths.

Genau deshalb sprechen viele beim Thema generische Compound Types von einer exponentiellen Komplexitätszunahme.

Warum das für Produktteams relevant ist

Das klingt schnell wie reine Sprachdiskussion. Im Projektalltag ist es aber ein Delivery-Thema.

Wenn ein Typmodell zu komplex wird, steigen für Teams:

  • Einarbeitungsaufwand,
  • Review-Kosten,
  • Fehlersuche in Randfällen,
  • Unsicherheit bei Refactorings.

Ich sehe dann häufig denselben Effekt. Code sieht hochtypisiert aus, aber die tatsächliche Verlässlichkeit steigt nicht im selben Maß, weil die Komplexität die Vorteile auffrisst.

Was ich stattdessen in PHP-Projekten mache

Ich versuche nicht, jede theoretisch mögliche Typkombination auszureizen. Ich optimiere auf Lesbarkeit, Prüfbarkeit und Betriebssicherheit.

Dafür nutze ich drei Leitlinien.

1) Unions an den Rändern, klare Typen im Kern

An Integrationsgrenzen akzeptiere ich Unions, wenn sie fachlich sinnvoll sind. Im Domänenkern führe ich möglichst früh auf klare, schmale Typen zurück.

2) Generics über statische Analyse, nicht über Laufzeitmagie

Ich arbeite konsequent mit PHPStan oder Psalm, @template und klaren Vertragsdefinitionen. So bekomme ich Typsicherheit, ohne die Laufzeit unnötig zu belasten.

3) Komplexität bewusst budgetieren

Für jeden zusätzlichen Typzweig stelle ich mir die Frage: Welchen konkreten Fehler verhindert das, und ist dieser Nutzen den kognitiven und technischen Aufwand wert?

Wenn ich das nicht sauber beantworten kann, vereinfache ich.

Ein pragmatisches Beispiel

Statt ein Repository mit sehr breiten Union-Typen zu bauen, trenne ich lieber in klarere Abstraktionen. Also zum Beispiel zwei fokussierte Repositories oder ein explizites Mapping an der Systemgrenze.

Das erzeugt oft etwas mehr Struktur, reduziert aber in der Regel Fehlersuche und Wartungskosten.

Für mich ist das der bessere Tausch.

Fazit

Union Types sind in PHP nützlich. In Kombination mit umfassenden Generics können sie aber schnell zu einem Komplexitäts- und Performanceproblem werden.

Ich gehe deshalb bewusst pragmatisch vor: klare Typen im Kern, gezielte Unions an den Rändern und starke statische Analyse im CI. So bleibt die Lösung verständlich, schnell und in Reviews sauber beherrschbar.

Wenn du magst, kannst du mit dem Projekt-Check prüfen, wie robust eure Architektur-, Test- und Typsicherheitsbasis aktuell ist.

Wenn du tiefer rein willst

Passende Vertiefungen zu diesem Thema

Wenn du nach dem Artikel tiefer in Umsetzung, typische Probleme oder Grundlagen einsteigen willst, helfen dir diese Seiten weiter.

Weitere Artikel