Heim > Web-Frontend > js-Tutorial > Rekursive bedingte Typen

Rekursive bedingte Typen

Barbara Streisand
Freigeben: 2024-12-01 03:00:13
Original
461 Leute haben es durchsucht

Recursive Conditional Types

Angenommen, Sie haben eine for-in-Schleife und stellen plötzlich fest, dass Ihr Variablentyp ein String und kein String-Literal-Union-Typ ist. Sie erhalten also diesen hässlichen Fehler, wenn Sie Ihre App mit tsc kompilieren, und ärgerlicherweise schreit Ihre Lieblings-IDE höchstwahrscheinlich aus vollem Halse:

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ user: number; nice: number; sys: number; idle: number; irq: number; }'.
  No index signature with a parameter of type 'string' was found on type '{ user: number; nice: number; sys: number; idle: number; irq: number; }'.ts(7053)
Nach dem Login kopieren

[!NOTE]

Nur ​​um Ihnen zu zeigen, wie es geht, verwende ich os.cpus. Dort versuche ich, cpu.times zu durchlaufen, was ein Objekt ist. Weitere Infos findest du hier.

Hier ist also der problematische Code:

import { cpus } from 'os';

const logicalCoresInfo = cpus();

for (const logicalCoreInfo of logicalCoresInfo) {
  let total = 0;
  for (const type in logicalCoreInfo.times) {
    total += logicalCoreInfo.times[type];  // Darn it, TS is upset!
  }
}
Nach dem Login kopieren

Fix

  1. Wir müssen die Schlüssel in logicalCoreInfo.times extrahieren und daraus einen neuen Typ erstellen.
  2. Dann können wir die Typzusicherung verwenden, um TS davon zu überzeugen, dass alles cool ist und wir wissen, was hier passiert.

Also fangen wir an. Im ersten Teil müssen wir einen benutzerdefinierten Dienstprogrammtyp für uns selbst erstellen. So wird unser endgültiger Dienstprogrammtyp aussehen:

type NestedKeysOf<T, K extends PropertyKey> = T extends object
  ? {
      [TKey in keyof T]-?:
        | (TKey extends K ? keyof T[TKey] : never)
        | NestedKeysOf<T[TKey], K>;
    }[keyof T]
  : never;
Nach dem Login kopieren

Lassen Sie es uns aufschlüsseln:

  1. T erweitert Objekt? ...: Never weist TS an, einen verschachtelten Objekttyp T rekursiv zu durchlaufen und Schlüssel eines bestimmten Schlüssels innerhalb von T zu extrahieren, wenn T ein Objekt ist.
  2. [TKey in Tonart von T]-? ist ein „Mapped Type“, der hier besonders nützlich ist, da wir den Namen der Schlüssel innerhalb des an diesen Dienstprogrammtyp übergebenen Objekts nicht kennen. Hier übergeben Sie logicalCoreInfo an ihn oder ein anderes Objekt, dann durchläuft es die Schlüssel, um daraus einen neuen Typ zu erstellen.

    Und -? Ist da, um die Optionalität zu entfernen, sodass wir einen String-Literal-Vereinigungstyp aller Schlüssel haben? Mit anderen Worten: { keyName?: string } wird als { keyName: string } behandelt.

  3. (TKey erweitert K ? keyof T[TKey] : nie) Überprüfen Sie, ob der aktuelle Schlüssel in der Iteration mit dem übergebenen Schlüssel (K) übereinstimmt. Wenn ja, werden alle darin enthaltenen Schlüssel als String-Literal-Union-Typ extrahiert und gib es zurück. Ansonsten gibt es nichts zurück.

  4. Wenn Schritt 3 dann kein Ergebnis erbracht hat, wird dieser Dienstprogrammtyp rekursiv auf T[Tkey] angewendet, sodass unsere Dienstprogrammfunktion auch bei verschachtelten Objekten funktioniert. Dies wird allgemein als „Rekursiver bedingter Typ“ bezeichnet.

  5. Schließlich bitten wir darum, die Vereinigung aller vom zugeordneten Typ generierten Typen zu nehmen. Kurz gesagt, wir reduzieren die verschachtelte Struktur.

Jetzt ist es also an der Zeit, es zu verwenden:

interface Person {
  name: string;
  address: {
    street: string;
    city: string;
  };
}

type KeysOfAddress = NestedKeysOf<Person, 'address'>; // "street" | "city"

// Or in our original example:
type CpuTimesKeys = NestedKeysOf<typeof logicalCoreInfo, 'times'>;
// ...
total += logicalCoreInfo.times[type as CpuTimesKeys];
// ...
Nach dem Login kopieren

Ref

  • TypeScript-Schlüssel des verschachtelten Objekttyps.

Das obige ist der detaillierte Inhalt vonRekursive bedingte Typen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:dev.to
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage