Verteilte Typen (Distributive Types) sind eine Funktion von TypeScript, die beim Arbeiten mit bedingten Typen (T extends U ? X : Y) auftritt. Wenn die Typ-Variable links von extends eine Vereinigung (union) ist, verteilt TypeScript die Bedingung auf jedes Element der Vereinigung.
Beispiel:
// "Test<A> | Test<B> | Test<C>" type Test<T> = T extends string ? () => string : () => number; type Result = Test<'A' | 'B' | 'C'>;
Hier wird Result verteilt als:
Wann werden sie angewendet — zur Erstellung von universellen APIs, zur Manipulation von Vereinigungen, z.B. zur Filterung oder Musterabgleich.
Besonderheiten:
[T] einwickelt, findet keine Verteilung statt. Das ist eine Möglichkeit, die Verteilung zu "deaktivieren".Frage: Wird der Typ T[] extends number[] ? true : false verteilt sein?
Die richtige Antwort: Nein, die Verteilung tritt nur ein, wenn links eine Typ-Variable ohne Verpackung in ein Array oder Tupel steht. Zum Beispiel, der bedingte Typ T extends number ? ... wird verteilen, aber T[] extends number[] ? ... — nicht.
Geschichte
Projekt: Eine Bibliothek zur Validierung von Props für React-Komponenten. Wir wollten einen Typ implementieren, der union-Props in ein strenges Interface umwandelt, aber aufgrund von Unkenntnis über die Verteilung wurde der Typ unerwartet komplex (Eigenschaften der Mitglieder der union vermischten sich). Wir haben es behoben, indem wir die Verpackung
[T]hinzugefügt haben, um die Verteilung zu verhindern.
Geschichte
Projekt: Wir haben alle Ereignistypen in einen einzelnen Handler integriert. Im bedingten Typ wurde erwartet, dass die Funktion jeden Ereignistyp über die Verteilung akzeptiert, aber ohne deren explizite Verwendung haben wir die Verarbeitung falsch implementiert, was zu fehlerhaften Argumenttypen führte (union statt eines separaten Aufrufs für jeden Typ).
Geschichte
Projekt: Bei der Erstellung eigener Hilfs-Typen (wie Exclude, Extract) haben wir vergessen, dass die Verteilung für Tupel und Arrays nicht stattfindet. Infolgedessen funktionierte der Typ Exclude nicht für Arrays (zum Beispiel, der Typ
Exclude<["a"|"b"], "b">entfernte "b" nicht).