Praktische TypeScript-Tipps, die Sie vielleicht nicht kennen

Praktische TypeScript-Tipps, die Sie vielleicht nicht kennen

Vorwort

Ich verwende Typescript schon seit langer Zeit, habe aber das Gefühl, dass ich es nicht voll ausgenutzt habe. Da viele Funktionen von TypeScript nicht verwendet werden, ist der Code, den ich zuvor geschrieben habe, voll davon, was leicht zu vielen Fehlern führen kann und nicht die wahre „Typ“-Leistung von TypeScript zum Vorschein bringt. In diesem Artikel sind einige Tipps zur Verwendung von Typescript zusammengefasst, die bei der zukünftigen Verwendung von Typescript hilfreich sein können.

Kommen wir ohne weitere Umschweife direkt zum Code.

Funktionsüberladung

Wenn Sie Benutzerparameter übergeben möchten, übergeben Sie kein Flag. Wenn Sie Paraparameter übergeben möchten, übergeben Sie ein Flag. Sie können schreiben:

Schnittstelle Benutzer {
  Name: Zeichenfolge;
  Alter: Anzahl;
}

const Benutzer = {
  Name: 'Jack',
  Alter: 123
};

Klasse IrgendeineKlasse {

  öffentlicher Test (Absatz: Benutzer): Nummer;
  öffentlicher Test (Absatz: Zahl, Flagge: Boolesch): Zahl;

  öffentlicher Test(Absatz: Benutzer | Zahl, Flagge?: Boolesch): Zahl {
    // Spezifische Implementierung return 1;
  }
}

const einigeClass = neue EinigeClass();

// OK
someClass.test(Benutzer);
einigeKlasse.test(123, false);

// Fehler
// einigeKlasse.test(123); 
//Argument vom Typ „Zahl“ kann nicht dem Parameter vom Typ „Benutzer“ zugewiesen werden.
// someClass.test(Benutzer, false);
//Argument vom Typ „{name: string; age: number; }“ kann keinem Parameter vom Typ „number“ zugewiesen werden.

Zuordnungstyp

Bevor Sie sich mit Zuordnungstypen vertraut machen, müssen Sie sich mit keyof, never, typeof und in vertraut machen.

keyof: keyof übernimmt den Schlüssel der Schnittstelle

Schnittstelle Punkt {
    x: Zahl;
    y: Zahl;
}

// Typ keys = "x" | "y"
Typschlüssel = Schlüssel von Punkt;

nie: ein Werttyp, der nie existiert

Offizielle Beschreibung:

der Typ „Never“ stellt den Typ von Werten dar, die niemals auftreten.

// Beispiel: Führen Sie eine umfassende Prüfung zur Kompilierungszeit durch. Typ Foo = Zeichenfolge | Zahl;

Funktion controlFlowAnalysisWithNever(foo: Foo) {
  wenn (Typ von foo === "Zeichenfolge") {
    // Hier wird foo auf den Typ string eingegrenzt } else if (typeof foo === "number") {
    // Hier wird foo auf den Typ Nummer eingegrenzt } else {
    // foo ist nie hier
    const-Prüfung: nie = foo;
  }
}

Verwenden Sie „never“, um das Hinzufügen eines neuen Union-Typs ohne entsprechende Implementierung zu vermeiden. Der Zweck besteht darin, absolut typsicheren Code zu schreiben.

typeof: Den Typ eines Wertes ermitteln

const a: Zahl = 3

// entspricht: const b: Zahl = 4
const b: Typ von a = 4

in: Prüft, ob eine Eigenschaft für ein Objekt vorhanden ist

Schnittstelle A {
  x: Zahl;
}

Schnittstelle B {
  y: Zeichenfolge;
}

Funktion macheStuff(q: A | B) {
  wenn ('x' in q) {
    // f: A
  } anders {
    // q: B
  }
}

Beim Mapping-Typ wird ein Typ einem anderen Typ zugeordnet. Einfach ausgedrückt konvertiert der neue Typ jedes Attribut des alten Typs in dieselbe Form.

Teilweise, schreibgeschützt, Nullwerte zulassend, Erforderlich

  • Partial wandelt jede Eigenschaft in eine optionale Eigenschaft um.
  • Readonly Wandelt jede Eigenschaft in eine schreibgeschützte Eigenschaft um.
  • Nullable wird in eine Vereinigung des alten Typs und Null umgewandelt.
  • Erforderlich macht jedes Attribut zu einem erforderlichen Attribut.
Typ Partial<T> = {
    [P in der Tonart T]?: T[P];
}

Typ schreibgeschützt<T> = {
    schreibgeschützt [P in Schlüssel von T]: T[P];
}

Typ Nullable<T> = { 
  [P in Tonart T]: T[P] | null 
}

Typ Erforderlich<T> = {
  [P in Tonart T]-?: T[P]
}

Schnittstelle Person {
    Name: Zeichenfolge;
    Alter: Anzahl;
}

Typ PersonPartial = Partial<Person>;
Typ PersonReadonly = Readonly<Person>;
Typ PersonNullable = Nullable<Person>;

Typ PersonPartial = {
    Name?: Zeichenfolge | nicht definiert;
    Alter?: Zahl | undefiniert;
}

Typ PersonReadonly = {
    schreibgeschützter Name: Zeichenfolge;
    schreibgeschütztes Alter: Zahl;
}

Typ PersonNullable = {
      Name: Zeichenfolge | null;
      Alter: Zahl | null;
}

Schnittstelle Requisiten {
  eine?: Zahl;
  b?: Zeichenfolge;
}

const obj: Props = { a: 5 };

const obj2: Erforderlich<Props> = { a: 5 };
// Eigenschaft „b“ fehlt im Typ „{ a: number; }“, ist aber im Typ „Required<Props>“ erforderlich.

Auswählen, Aufzeichnen

  • Pick wählt eine Reihe von Attributen aus, um einen neuen Typ anzugeben
  • Record erstellt eine Reihe von Attributen, um einen neuen Typ anzugeben. Dies wird häufig zum Deklarieren gewöhnlicher Object-Objekte verwendet.
Typ Pick<T, K erweitert Schlüssel von T> = {
  [P in K]: T[P];
}

Typ Record<K erweitert Schlüssel von jedem, T> = {
  [P in K]: T;
}

Schnittstelle Todo {
  Titel: Zeichenfolge;
  Beschreibung: Zeichenfolge;
  abgeschlossen: Boolesch;
}

Typ TodoPreview = Pick<Todo, "Titel" | "abgeschlossen">;

const todo: TodoPreview = {
  Titel: "Reinraum",
  abgeschlossen: falsch,
};

todo; // = const todo: TodoVorschau


Schnittstelle PageInfo {
  Titel: Zeichenfolge;
}

Typ Seite = "Home" | "Über" | "Kontakt";

const nav: Datensatz<Seite, Seiteninfo> = {
  über: { Titel: "Titel1" },
  Kontakt: { Titel: "title2" },
  Startseite: { Titel: "title3" },
};

nav.about; // = const nav: Datensatz

Ausschließen, Weglassen

  • Ausschließen entfernt die Schnittmenge und gibt den verbleibenden Teil zurück.
  • Omit gilt für Exclude von Schlüssel-Wert-Paar-Objekten und entfernt die im Typ enthaltenen Schlüssel-Wert-Paare.
Typ Exclude<T, U> = T erweitert U? nie : T
Typ Omit = Pick<T, Exclude<keyof T, K>>

// entspricht: Typ A = 'a'
Typ A = Ausschließen<'x' | 'a', 'x' | 'y' | 'z'>

Schnittstelle Todo {
  Titel: Zeichenfolge;
  Beschreibung: Zeichenfolge;
  abgeschlossen: Boolesch;
}

Typ TodoPreview = Omit<Todo, "Beschreibung">;

const todo: TodoPreview = {
  Titel: "a",
  abgeschlossen: falsch,
};

Rückgabetyp

Holen Sie sich den Rückgabewerttyp, normalerweise eine Funktion

Typ ReturnType<T erweitert (...args: beliebig) => beliebig>
  = T erweitert (...Argumente: beliebig) => R folgern? R: beliebig;

Deklarieren Sie die Funktion f1(): { a: Zahl; b: Zeichenfolge };
Typ T1 = ReturnType<Typ von f1>;
// Typ T1 = {
// a: Zahl;
// b: Zeichenfolge;
// }

Es gibt noch viele weitere Zuordnungstypen, siehe die Utility-Typen-Referenz.

Typzusicherungen

Typbehauptungen werden verwendet, um TypeScript den detaillierten Typ eines Wertes explizit mitzuteilen. Die richtige Verwendung kann unseren Arbeitsaufwand reduzieren.

Beispielsweise hat eine Variable keinen Anfangswert, aber wir kennen ihre Typinformationen (sie können vom Backend zurückgegeben werden). Gibt es eine Möglichkeit, die Typinformationen korrekt abzuleiten und sie normal auszuführen? Eine empfohlene Onlinemethode besteht darin, einen Anfangswert festzulegen und dann typeof zu verwenden, um den Typ abzurufen (der möglicherweise an anderer Stelle verwendet wird). Sie können zur Lösung dieses Problems auch Typbehauptungen verwenden:

Schnittstelle Benutzer { 
    Name: Zeichenfolge; 
    Alter: Anzahl; 
}

exportiere Standardklasse irgendeineKlasse { 
    privater Benutzer = {} als Benutzer;
} 

aufzählen

Aufzählungstypen werden in numerische Typen und Zeichenfolgentypen unterteilt, wobei numerische Aufzählungen als Flags verwendet werden können:

Aufzählung AnimalFlags {
    Keine = 0, 
    HasClaws = 1 << 0, 
    KannFliegen = 1 << 1, 
    HasClawsOrCanFly = HasClaws | KannFliegen 
}

Schnittstelle Tier { 
    Flaggen: Tierflaggen; 
   [Schlüssel: Zeichenfolge]: beliebig; 
}

Funktion printAnimalAbilities(Tier: Tier) { 
    var TierFlags = Tier.Flags; 
    wenn (animalFlags & AnimalFlags.HasClaws) { 
        console.log('Tier hat Krallen'); 
    } 
    wenn (Tierflaggen & Tierflaggen.KannFliegen) { 
        console.log('Tier kann fliegen'); 
    } 
    wenn (Tierflaggen == Tierflaggen.Keine) { 
        console.log('nichts'); 
    } 
}

var Tier = { Flags: AnimalFlags.None }; 
printAnimalAbilities(animal); // nichts 
animal.flags |= AnimalFlags.HasClaws; 
printAnimalAbilities(Tier); // Tier hat Krallen 
Tier.Flags &= ~AnimalFlags.HasClaws; 
printAnimalAbilities(animal); // nichts 
animal.flags |= AnimalFlags.HatKrallen | AnimalFlags.KannFliegen; 
printAnimalAbilities(Tier); // Tier hat Krallen, Tier kann fliegen 

  • Verwenden Sie |=, um eine Flagge hinzuzufügen;
  • Verwenden Sie &= und ~ zusammen, um eine Flagge zu löschen;
  • | um Flaggen zu kombinieren.

Dies wird möglicherweise nicht häufig verwendet. Wir können auch ähnlichen Code im Typescript-Quellcode zu Typen sehen:

Eine Aufzählung vom Typ String kann Konstanten verwalten:

const enum TODO_STATUS {
  TODO = "Zu erledigen",
  DONE = "FERTIG",
  TUN = 'TUN'
}

Funktion todos (Status: TODO_STATUS): Todo[];

Aufgaben(TODO_STATUS.TODO)

Tupel

Stellt ein Array mit bekannter Anzahl und Art von Elementen dar, die nicht vom gleichen Typ sein müssen.

let x: [Zeichenfolge, Zahl];
x = ['hallo', 10]; 

Bei Mehrfachanfragen können Sie Folgendes beantragen:

const requestList: any[] = [http.get<A>('http://some.1')]; // Auf any[] Typ setzen, wenn (Flag) { 
    Anfrageliste[1] = (http.get<B>('http://some.2')); 
} 
const [ { data: a }, response ] = warte auf Promise.all(requestList) als [Antwort<A>, Antwort<B>?]

Paradigma

Nachdem Generika definiert wurden, können sie auf zwei Arten verwendet werden: Eine besteht darin, den generischen Typ zu übergeben, und die andere darin, die Typinferenz zu verwenden.

Deklariere Funktion fn<T>(arg: T): T; // Definiere eine generische Funktion const fn1 = fn<string>('hello'); // Die erste Möglichkeit besteht darin, den generischen Typ String zu übergeben const fn2 = fn(1); // Die zweite Möglichkeit besteht darin, aus dem Typ number, der durch den Parameter arg übergeben wird, abzuleiten, dass der Typ des generischen T eine Zahl ist 

Ein Beispiel für den Aufbau einer Baumstruktur aus einer flachen Array-Struktur:

// Daten vor der Konvertierung const arr = [ 
{ id: 1, parentId: 0, name: 'test1'}, 
{ id: 2, parentId: 1, name: 'test2'}, 
{ id: 3, parentId: 0, name: 'test3'} 
]; 
// Nach der Konvertierung [{ id: 1, parentId: 0, name: 'test1', 
    Kinderliste: [ { id: 2, parentId: 1, name: 'test2', Kinderliste: [] } ] }, 
    { id: 3, parentId: 0, name: 'test3', childrenList: [] } 
]


Schnittstelle Element { 
    ID: Nummer; 
    parentId: Nummer; 
    Name: Zeichenfolge; 
}

// Den Typ des childrenKey aus dem übergebenen Optionsparameter abrufen und dann an TreeItem übergeben

Schnittstelle Optionen<T erweitert Zeichenfolge> { 
    KinderSchlüssel: T; 
} 
Typ TreeItem<T erweitert Zeichenfolge> = Item & { [Schlüssel in T]: TreeItem<T>[] | [] }; 
Deklarieren Sie die Funktion listToTree<T extends string = 'children'>(list: Item[], options: Options<T>): TreeItem<T>[]; 
listToTree(arr, { childrenKey: 'childrenList' }).fürJedes(i => i.childrenList) 

schließen

Stellt die Typvariable dar, die in einer erweiterten bedingten Anweisung abgeleitet werden soll.

Typ ParamType<T> = T erweitert (Param: folgern P) => beliebig? P : T; 

Das bedeutet: wenn T (param: infer P) => any zugewiesen werden kann, ist das Ergebnis der Parameter P im Typ (param: infer P) => any, andernfalls gibt es T zurück.

Schnittstelle Benutzer { 
    Name: Zeichenfolge; 
    Alter: Anzahl; 
} 
Typ Func = (Benutzer: Benutzer) => void 
Typ Param = ParamType<Func>; // Param = Benutzer 
Typ AA = ParamType<Zeichenfolge>; // Zeichenfolge

Beispiel:

// [Zeichenfolge, Zahl] -> Zeichenfolge | Zahl
Typ ElementOf<T> = T erweitert Array<infer E>? E: nie;

Typ TTuple = [Zeichenfolge, Zahl];

Typ ToUnion = ElementOf<TTuple>; // Zeichenfolge | Zahl


// T1 | T2 -> T1 & T2
Typ UnionToIntersection<U> = (U erweitert beliebig? (k: U) => ungültig: nie) erweitert ((k: folgere I) => ungültig)? I: nie;

Typ Ergebnis = KreuzungZuSchnittpunkt<T1 | T2>; // T1 & T2

Zusammenfassen

Typescript ist in Bezug auf Typbeschränkungen sehr leistungsfähig. Aufgrund der begrenzten Anzahl von Artikeln gibt es andere Typen wie Union-Typen, Schnittmengentypen usw. Leser können die Informationen selbst überprüfen. Wenn Sie zum ersten Mal mit Paradigmen und ihren verschiedenen Kombinationen in Berührung kommen, fühlen Sie sich möglicherweise ungewohnt. Dann werden Sie sie langsam im Projekt anwenden und versuchen, Fehler zu minimieren.

Dies ist das Ende dieses Artikels über praktische Tipps für Typescript. Weitere relevante praktische Tipps für Typescript finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen!

Das könnte Sie auch interessieren:
  • 6 praktische Tipps für die TypeScript-Entwicklung
  • TypeScript verweist auf Ressourcendateien und weist bei der Ausnahmebehandlung darauf hin, dass diese nicht gefunden werden können
  • ​​​​​​​Teilen Sie 7 praktische TypeScript-Einzeiler

<<:  Analyse des Unterschieds zwischen der Verwendung von Left Join-Einstellungsbedingungen in „on“ und „where“ in MySQL

>>:  Beispielanalyse der Verwendung des neuen JSON-Feldtyps in MySQL 5.7

Artikel empfehlen

Beispiel einer DOM-Operationstabelle (DOM erstellt Tabelle)

1. Erstellen Sie eine Tabelle mit HTML-Tags: Code...

Einführung in den vollständigen Namen und die Funktion von HTML-Tags

Alphabetisch DTD: Gibt an, in welcher XHTML 1.0 D...

Benutzerdefinierte Komponente der unteren Navigationsleiste des WeChat-Applets

In diesem Artikelbeispiel wird der spezifische Im...

Änderung und Abfrage von Python MySQL-Datenbanktabellen

Python stellt eine Verbindung zu MySQL her, um Da...

Tomcat8 verwendet Cronolog zum Aufteilen von Catalina.Out-Protokollen

Hintergrund Wenn die von Tomcat generierte catali...

So definieren Sie Eingabetyp=Dateistil

Warum die Dateisteuerung verschönern? Stellen Sie ...