ProgrammierungFrontend Entwickler

Was sind verteilte Typen (Distributive Types) in TypeScript, wo werden sie angewendet und welche Besonderheiten sind bei der Arbeit mit ihnen zu beachten?

Bestehen Sie Vorstellungsgespräche mit dem Hintsage-KI-Assistenten

Antwort

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:

  • Test<'A'> | Test<'B'> | Test<'C'>

Wann werden sie angewendet — zur Erstellung von universellen APIs, zur Manipulation von Vereinigungen, z.B. zur Filterung oder Musterabgleich.

Besonderheiten:

  • Wenn man T in ein Tupel [T] einwickelt, findet keine Verteilung statt. Das ist eine Möglichkeit, die Verteilung zu "deaktivieren".
  • Die Verteilung funktioniert nur für Typ-Variablen (nicht für Literale).

Fangfrage

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.


Beispiele realer Fehler aufgrund mangelnden Wissens über die Feinheiten des Themas


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).